2

sed でシェル ワイルドカードを使用しようとしています。以下は失敗します。(出力として期待fooしています。)

$ touch foo
$ ls
foo
$ echo *
foo
$ bar=*
$ echo $bar
foo
$ echo "$bar"
*
$ echo replace | sed "s/replace/${bar}/"
*
$ echo replace | sed "s/replace/"${bar}"/"
*

予想どおり、 (二重) 引用符で囲まれているためfoo、最後から 2 番目のコマンドは を生成しません。${bar}ただし、最後のコマンドでワイルドカードを展開することを期待していました。

ただし、次の後にいずれかのコマンドを機能させることができます。

bar=$(echo *)

さらに、次のシェルのワイルドカード展開を期待していましたが、これは発生しません。

$ echo replace | sed s/replace/*/
*

ただし、これは機能します。

$ echo replace | sed s/replace/$(echo *)/
qwe
4

1 に答える 1

3

最後のコマンドは、ワイルドカードを展開しようとしますが、失敗します。からman bash:

 Pathname Expansion
        After  word  splitting,  unless  the -f option has been set, bash
        scans each word for the characters *, ?, and [.  If one of these
        characters appears, then the word is regarded as a pattern, and
        replaced with an alphabetically sorted list of file names matching
        the  pattern.

それが言うように、bash は a を含む各単語を*一致するファイル名に展開しようとします。あなたの場合、で始まるファイル名に展開しようとしますs/replace/が、そのようなファイルはありません。これを証明するには:

$ echo "aaaa" | sed "s@a@*@g"
****

$ echo "aaaa" | sed "s@a@"*"@g"
****

$ touch s@a@b@g

$ echo "aaaa" | sed "s@a@*@g"
****

$ echo "aaaa" | sed "s@a@"*"@g"
bbbb

問題の解決策については、コメントに記載されているようにサブシェル展開を使用できます。

于 2013-10-20T13:13:41.927 に答える