変数付きsedコマンドを使用する

変数付きsedコマンドを使用する

Stack Overflow や関連 Web サイトで利用可能なあらゆる解決策を試しましたが、解決策は見つかりませんでした。この問題にかなりの時間を費やし、ようやくこの質問を投稿しました。

シェル変数でコマンドを使いたいのですがsed、スクリプトは非常にシンプルです。

## string to replace is the text after comma in the variable pc.
to_replace=${pc#*,}
echo $to_replace

##text to be replaced by the following line
replace_with="PARTITIONED BY ($pc1);"
echo $replace_with

## use sed command to replace.
sed "s@$to_replace@$replace_with@" $entry  ## $entry is the variable that contains the file name

2 つのechoコマンドはそれぞれ次の出力を生成します。

PARTITIONEDED BY (date_key );  ## the text I want to be replaced
PARTITIONED BY ( date_key int );  ## the text I want to replace with

エラーが発生します:

sed: -e expression #1, char 2: unterminated `s' command

または、テキストがまったく置き換えられません。

誰か助けてください。私は Centos 6 を使用しています (それが問題なら)。よろしくお願いします!

答え1

sed: -e expression #1, char 2: unterminated `s' command

エラー メッセージには、エラーが 2 番目の文字で発生すると書かれていますが、これは不思議です。最初の変数の先頭に改行を入れることで、これを再現できます。

$ a=$'\nfoo'
$ b='bar'
$ sed "s@$a@$b@"
sed: -e expression #1, char 2: unterminated `s' command

エスケープされていない改行は sed コマンドを終了します。改行を後から入れると、aもちろん後の文字でエラーが発生します。

スクリプトの前半で両方の変数を出力しましたが、引用符で囲まれていなかったため、先頭の空白は削除され、中間の空白は単一のスペースとして表示されます。

次のようにして、変数に実際に含まれている内容を確認します。

printf ">%s<\n" "$to_replace"
printf "%q\n" "$to_replace"

後者は、Bash が入力として受け入れる方法で引用符で囲まれた文字列を表示する Bash の機能です。sedset -xのコマンド ラインに何が送られるかも表示されますが、出力からリテラルの改行に注意する必要があります。

したがって、先頭の改行が 1 つだけの場合は、スクリプトの先頭でそれを削除できます。

to_replace=${pc#*,}
to_replace=${to_replace#$'\n'}

(これらを 1 つに組み合わせることもできますが、改行がなくても個別の手順が機能します。)

答え2

これを試して

sed -i -e "s@$to_replace@$replace_with@g" "$entry"

どこ

  • -iは「その場で」置換することを意味します。置換を使用しない場合は-i標準出力に出力されます。

関連情報