sedが終了していない「s」のエラーを表示するのはなぜですか?

sedが終了していない「s」のエラーを表示するのはなぜですか?

Bashスクリプトにsed代替セットがあり、終了していない「s」コマンドでエラーが発生します。 sed 行は次のとおりです。

sed -n -e "s/TMPFOO1/$FOO1/" -e "s/TMPFOO2/$FOO2/" -e "s/TMPFOO3/$FOO3/" -e "s/TMPFOO4/$FOO4/" -e "s/TMPFOO5/$FOO5/" /home/foo/template > /home/foo/template/finishedresult

しかし、何らかの理由でbashはこれを気に入らず、エラーが発生します。

sed: -e expression #4, char 69: unterminated `s' command

私がここで何を見逃しているのでしょうか? SED入力変数の作成方法は?私の考えではすべて終了しました。

答え1

置換はsed以外のシェルで行われるため、sedコマンドに変数を安全に挿入することはできません。変数の値はsed構文になります。たとえば、に改行文字が含まれている"s/TMPFOO1/$FOO1/"と、$FOO1観察したものと同様の構文エラーが発生します。$FOO1aが含まれると、コマンドが/終了sし、エラーが発生したり、他のコマンドが実行される可能性があります(次の内容が/有効なsed構文の場合)。

FOO1sedコマンドに含めるために特殊文字を引用するために最初の代替パスを実行できますが、awkを使用する方がはるかに簡単です。 awkには、変数の概念と変数の初期値を設定するコマンドライン構文があります。

awk -v FOO1="$FOO1" -v FOO2="$FOO2" -v FOO3="$FOO3" -v FOO4="$FOO4" -v FOO5="$FOO5" '{
    sub(/TMPFOO1/, FOO1);
    sub(/TMPFOO2/, FOO2);
    sub(/TMPFOO3/, FOO3);
    sub(/TMPFOO4/, FOO4);
    sub(/TMPFOO5/, FOO5);
    print;
}' /home/foo/template > /home/foo/template/finishedresult

答え2

変数の1つに$FOOで解釈される特殊文字が含まれている可能性が高いですsed

異なるエラーメッセージを生成する別のバージョンがありますが、sed以下は同様の問題の例です。

$ VAR=a
$ echo i | sed -e "s/i/"$VAR"/"
a
$ tmp> VAR=/
$ echo i | sed -e "s/i/"$VAR"/"
sed: 1: "s/i///
": bad flag in substitute command: '/'

この場合、末尾のスラッシュ$VARとして解釈される文字が含まれます。sed

答え3

他の人がここで述べたように、FOO *変数の内容によって異なります。あなたの場合にはsedいくつかの特殊文字が含まれる可能性があるため、使用は間違った選択です。

見てこのリンクそして機能を見てくださいgsub_literal

stdinから読み込んでstdoutに書き込むので、gsub_literal使い方は次のとおりです。

gsub_literal "$search" "$replace" < /home/foo/template > /home/foo/template/finishedresult

出力例:

rany$ cat > foo.txt
a'
a'

rany$ gsub_literal a\' b < foo.txt 
b
b

答え4

コマンドにバックスラッシュを追加すると問題が解決しましたsed 's/.../.../g'。このコマンド

sed 's/\"a/ä/g' input_file

私にこのようなエラーメッセージを与えた

sed: -e 式 #1、文字 9: 終了していない 's' コマンド

c-shellスクリプトの一部として実行されると、これは最新バージョンに対してのみ実行され、sed以前のバージョンでは実行されません。 (奇妙なことに、tc-shellのコマンドラインで同じコマンドを入力すると正常に動作します。)

c-shellスクリプトの問題は、文字の前にバックスラッシュを追加することで解決されましたä

sed 's/\"a/\ä/g' input_file

関連情報