テキストファイル内の文字列を、できればsedを使用して1 2 3 4 5 67などの一連の数字に置き換えたい。
これが私が(検索文字列なしで)試したもので、うまくいくようです:
for i in {1..5};do echo $(seq 1 $i); done
出力:
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
しかし、私がこれを試すと:
for i in {1..5};do sed -i "s/abc/$(seq 1 $i)/g" test; done
次のエラーが発生します。
sed: -e expression #1, char 8: unterminated `s' command
sed: -e expression #1, char 8: unterminated `s' command
sed: -e expression #1, char 8: unterminated `s' command
sed: -e expression #1, char 8: unterminated `s' command
置換文字列も角かっこで囲んでみましたが、うまくいかないようです。
最初のループ
for i in {1..5}
いくつかのパラメータを置き換えたいファイル名のグロブに置き換えられます。
TL; DR:
これを回避する方法はいくつかありますが、サンプルケースで最もクリーンな方法は次のとおりです。
_for i in {1..5};do sed -i "s/abc/$(seq -s ' ' 1 $i)/g" test; done
_
つまり、seq
に、各数値を区切るために1つのスペースを使用するように要求します。
説明:
これらのエラーが発生した理由は、次の出力が原因です。
_seq 1 5
_
ではありません:
_1 2 3 4 5
_
むしろ:
_1
2
3
4
5
_
また、$(seq 1 $i)
コマンド置換 を二重引用符で囲んだため、通常の 単語分割 は実行されず、すべての改行(最後を除く)が実行されます。 seq
ユーティリティによる出力はそのままです。
したがって、実際のsed
コマンドは次のようになります。
_sed -i "s/abc/1
2
3
4
5
/g" test
_
sed
に関する限り、_s/abc/1
_コマンドを指定したため、つまり、必要な最後の_/
_がないため、これは受け入れられません。
echo $(seq 1 5)
は二重引用符で囲まれていないため、$(seq 1 5)
は_1 2 3 4 5
_を出力します。したがって、単語分割はシェルのデフォルトの動作に従って行われます。
実際、次のようにサンプルケースを修正する場合があります。
_for i in {1..5};do sed -i "s/abc/$(echo $(seq 1 $i))/g" test; done
_
つまり、コマンド置換(元の_seq 1 $i
_)inside別のコマンド置換(echo
1)を実行します。
$(echo ...)
コマンド置換はnotではないサブシェルで実行されるため、これは二重引用符内でも機能します。 )「I-am-inside-a-double-quote」状態であるため、seq
からの出力に対するワード分割はそこで実行されます。
出力を一時ファイルにパイプしてから、一時ファイルを元のファイルの上に移動できます。また、mayは、一度に1行で操作することを意味します。その場合、g
を削除する必要があります。
for i in {1..5}; do
sed -e "s/abc/$(seq 1 $i)/" test > test.tmp
mv test.tmp test
done