2

現在、次の方法で特定のテキスト ファイルのリストに項目を追加する完全に機能する sed コマンドがあります...

ITEMS="$ITEM1 $ITEM2 $ITEM3"

挿入したい場合は次のようになり$ITEM4ます...

ITEMS="$ITEM1 $ITEM2 $ITEM3 $ITEM4"

リスト内の項目数は不明です。それは動的です。そして、そのテキストのドル記号と引用符は文字通りに解釈されます。

次のコマンドを使用して、リストへの追加を完了します (変数$itemNumは別の場所に割り当てられます) ...

sed "/^\s*ITEMS=/s/\"$/ \$ITEM$itemNum&/" file.txt

もちろん、これが行うことは、で始まる行ITEMS=(および場合によっては先頭のスペース) を見つけ、その行の最後の二重引用符をスペースと目的の項目と二重引用符に置き換えることです (置き換えられた二重引用符を元の位置に戻すため)。 )。ただし、次のようにITEMSリストが空になる可能性がある追加のケースがあります...

ITEMS=""

この場合、私のコマンドは次$ITEM4のようにリストの最後に挿入されます...

ITEMS=" $ITEM4"

ただし、コマンドで空のリストを説明し、リストが実際に空の場合は先頭のスペースを入れないようにしたいので、次のようになります...

ITEMS="$ITEM4"

これを最もよく達成するために既存のコマンドをどのように変更できますか?

4

2 に答える 2

3

あなたの主題をガイドとして、sedで条件付きでそれを行う1つの方法を次に示します。

sed -e '/^\s*ITEMS=/{s/=""/="$ITEM'"$itemNum"'"/;t;s/"$/ $ITEM'"$itemNum&/;}" file.txt

主な変更点は、空の引用符 ("") を最初に置き換えようとしたことです。それが成功した場合、条件分岐 t により、他の置換をバイパスしてスクリプトの最後に送られます。2 番目の置換は、最初の置換が失敗した場合にのみ発生します。「傾いたつまようじ」の一部を取り除くために引用を変更しましたが、元のコマンドの約 66% です。

編集:OPのリクエストによる「傾いたつまようじ」のこと

オリジナルでは sed スクリプト行全体を二重引用符で囲んだため、すべての " とほとんどの $ をバックスラッシュでエスケープする必要がありました。私のバージョンをそのように書き換えると、次のようになります。

sed -e "/^\s*ITEMS=/{s/=\"\"/=\"\$ITEM$itemNum\"/;t;s/\"$/ \$ITEM$itemNum&/;}" file.txt

これらのバックスラッシュはすべて気を散らすものだと思うので、できる限り多くを一重引用符で囲み、$itemNum だけを二重引用符で囲みます。シェル スクリプトでは、2 つの文字列が隣接している場合、それらがくっつくので、var1=QRS; var2='ABC'$var1'XYZ'var2 を 'ABCQRSXYZ' に設定したままにします。変数にスペースが含まれる可能性があると思われる場合は、それを引用するのが最善です: var1=QRS; var2='ABC'"$var1"'XYZ'(' の間にスペースはありません)。 」と「」があります。

于 2013-03-29T18:09:35.990 に答える
1

この状況では、awk の方が柔軟性があります。

awk -F'"' -vn="$itemNum" '/^\s*ITEMS=/{sub(/"$/,($2?" ":"")"$ITEM"n"&")}1' file

テスト:

kent$  itemNum=4 
kent$  echo 'ITEMS=""'|awk -F'"' -vn="$itemNum" '/^\s*ITEMS=/{sub(/"$/,($2?" ":"")"$ITEM"n"&")}1'
ITEMS="$ITEM4"
kent$  echo 'ITEMS="$ITEM1 $ITEM2 $ITEM3"'|awk -F'"' -vn="$itemNum" '/^\s*ITEMS=/{sub(/"$/,($2?" ":"")"$ITEM"n"&")}1'                                                       
ITEMS="$ITEM1 $ITEM2 $ITEM3 $ITEM4"
于 2013-03-29T17:43:56.620 に答える