sedを使用して文字列パターンをシーケンスに置き換える

sedを使用して文字列パターンをシーケンスに置き換える

テキストファイルの文字列をsedを使用して1 2 3 4 5 6 7などの一連の数字に置き換えたいと思います。

これは私が(検索文字列なしで)試みたもので、うまくいくようです。

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}

一部のパラメータを置き換えるファイル名で置き換えるglob。

答え1

TL;博士:

これにはいくつかの方法があります。あなたのケースに最適な方法は次のとおりです。

for i in {1..5};do sed -i "s/abc/$(seq -s ' ' 1 $i)/g" test; done

つまり、seq各番号を区切るにはスペースが必要です。

説明する:

このようなエラーが発生する理由は出力によるものです。

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

現時点では、必須 Final が欠落しているコマンドをsed 提供しているため、これは許可されません。s/abc/1/

Anは二重引用符内にないため、echo $(seq 1 5)印刷するため、シェルのデフォルトの動作に応じて単語の区切りが発生します。1 2 3 4 5$(seq 1 5)

実際、次のように例を修正できます。

for i in {1..5};do sed -i "s/abc/$(echo $(seq 1 $i))/g" test; done

つまり、コマンドを実行して(元のseq 1 $i)を置き換えます。~へ他のコマンドは(echoa)を置き換えます。

$(echo ...)コマンド置換が内部にあるため、二重引用符内でも機能します。サブシェルこれはいいえ「I-am-inside-a-double-quote」状態なので、出力はトークン化されます。seq 〜するそこでやってください。

答え2

出力を一時ファイルにパイプし、一時ファイルを元のファイルの上に移動できます。あなたは可能一度に1行しか機能しないように意図されており、この場合は以下を削除する必要がありますg

for i in {1..5}; do
    sed -e "s/abc/$(seq 1 $i)/" test > test.tmp
    mv test.tmp test
done

関連情報