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


9

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に変数を入力させるにはどうすればよいですか?それらはすべて終了しているように見えます。


2
$ FOO4には、sed sコマンドが終了しないようにする奇妙なものが含まれています(例: "\"または "\\"?)。(そのため、後続の「\」が次の「/」をsコマンドの終了文字としてではなく、置換文字列の文字部分として扱われると思います)
Olivier Dulac

回答:


7

置換はsedではなくシェルによって実行されるため、sedコマンドの変数を安全に補間することはできません。変数の値はsed構文になります。たとえば、では"s/TMPFOO1/$FOO1/"$FOO1改行が含まれていると、観察したような構文エラーが発生します。$FOO1が含まれている場合/、これにより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

些細な注意:- -v各変数宣言の前にa を付ける必要があります。
Mike B

@MikeBバグレポートをありがとう。通常、このようなタイプミスが見つかった場合は、投稿を直接編集してください。
Gilles「SO-邪悪なことをやめなさい」

著者以外の@Gilles編集は6文字以上である必要があります。
NobleUplift 2014

6

ほとんどの場合、$FOO変数の1つにによって解釈される特殊文字が含まれてい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れる文字が含まれています。


2

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

見てみましょうこのリンクをして関数を参照してくださいgsub_literal

gsub_literalstdin から読み取り、stdoutに書き込むため、使用法は次のようになります。

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

1

この問題は、sed 's/.../.../g'コマンド内で追加のバックスラッシュを試すことで解決されました。このコマンド

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

このエラーメッセージが表示されました

sed:-e expression#1、char 9:終了していない `s 'コマンド

c-shellスクリプトの一部として実行されたとき、それはsed古いバージョンではなく、最近のバージョンでのみ実行されました。(奇妙なことに、同じコマンドがコマンドラインで(tcシェルで)指定された場合は正常に機能します)。

cシェルスクリプトの問題は、ä文字の前にバックスラッシュを付けることで修正されています。

sed 's/\"a/\ä/g' input_file
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.