Bashでは、次のファイルが提供されます。
$ cat noquotes.txt
s/a/b/g
$ cat quotes.txt
"s/a/b/g"
なぜ
$ echo "aaa" | sed -e $(cat noquotes.txt)
bbb
成功したけど
$ echo "aaa" | sed -e $(cat quotes.txt)
sed: 1: ""s/a/b/g"
": invalid command code "
失敗する?
先に実行してみるとset -x
わかるけど
$ echo "aaa" | sed -e $(cat noquotes.txt)
+ echo aaa
++ cat noquotes.txt
+ sed -e s/a/b/g
bbb
そして
$ echo "aaa" | sed -e $(cat quotes.txt)
+ echo aaa
++ cat quotes.txt
+ sed -e '"s/a/b/g"'
sed: 1: ""s/a/b/g"
": invalid command code "
したがって、内容の周囲に追加の引用符が挿入されていますが、内容のnoquotes.txt
周囲には挿入されていないようですquotes.txt
。
答え1
コマンドライン処理には、次の手順があります。見積もりの削除ステップ。これは通常、コマンドが実行される前に発生する最後の操作であり、コマンドから文字列を引用するために使用された外部引用符のセットを削除します。
次のコマンドの場合
sed -e "s/a/b/g"
このステップでは、コマンドに最後の引数としてsed
文字列が与えられていることを確認します。s/a/b/g
いいえ "s/a/b/g"
。
"s/a/b/g"
コマンド置換でファイルを使用して文字列を読み取るとき、引用符cat
は元のコマンドの一部ではないため削除されません(ファイルから読み取られたデータの一部です)。
これは、リテラル文字列が実行される式としてsed
受け取られるため、初期値を理解していないと文句を言います(コマンドが必要です)。"s/a/b/g"
"
sed
トレースされた出力はset -x
デバッグ出力としてのみ処理されます。シェルは、bash
トレース内の特定の文字を含む文字列の周りに引用符を追加するため、個々の引数の引用符を表しません。実際にまたは、呼び出されたユーティリティがそれを解釈する方法です。
sed
ただし、ファイルから編集スクリプトを実行するには、次の-f
オプションを使用します。
sed -f noquotes.txt <<<"aaa"
またy
、このコマンドをsed
使用すると、with置換を使用するよりも効率的に個々の文字セットを翻訳できますs
。あなたのs/a/b/g
代替品として書くのが最善ですy/a/b/
。
もしこれならただこれが必要な場合は、より簡単なtr
ユーティリティを使用する方が効率的です。
tr a b <<<"aaa"
答え2
したがって、quotes.txtの周りではなく、noquotes.txtの内容の周りに別々の引用符が挿入されているようです。
これはちょうどBashを助けることです。 Bashが解釈する記号があるたびに、物事の周りに引用符を付けることがわかります。必要な場合にのみ引用符を使用してユーザーと同じように動作します。 quote.txtに次のいずれかを入力してください。
s/a$/a/g
s/"hi"/"bye"/g
リストは非常に長いかもしれません。
さて、元の質問に戻ります。まず、sed
奇妙なメッセージを印刷します。set -x
入力が"s/a/b/g"
でないことは明らかです""s/a/b/g"
。私はこのニュースを信じません。 GNU sed 4.2.1が印刷する内容は次のとおりです"s/a/b/g"
。
$ sed -e '"s/a/b/g"'
sed: -e expression #1, char 1: unknown command: `"'
非常に明確に言えば、最初の文字はコマンド名であり、名前付きコマンドがないため、"
何sed
をすべきかわかりません。