
1を入力してください:
find . -maxdepth 1 -name "* *" -exec bash -c 'sed -n '1p' <(echo $1)' h {} \;
出力1:
./file with space
2を入力してください:
find . -maxdepth 1 -name "* *" -exec bash -c 'sed "1s_ _._" <(echo $1)' h {} \;
出力2:
./file.with.space
3を入力してください:
find . -maxdepth 1 -name "* *" -exec bash -c 'sed '1s_ _o_' <(echo $1)' h {} \;
出力3:
sed: -e expression #1, char 3: unterminated `s' command
出力3が間違っているのはなぜですか?この場合、一重引用符と二重引用符の違いは何ですか?
答え1
シェルの解析後、3番目のコマンドは、、、、、、、、、、、、、、、、、、、、、でfind
構成されます。次の引数と同様に、スペースは単一引用符リテラル内にあるため、単語は単一の引数です。したがって、到着するとパラメータ、、、、で実行されます。シェルスクリプトはパラメータ付きのコマンドであり、これは正しい形式のsedスクリプトではありません。.
-maxdepth
1
-name
* *
-exec
bash
-c
sed 1s_
_o_ <(echo $1)
h
{}
;
sed 1s_
find
./file with space
bash
-c
sed 1s_
_o_ <(echo $1)
h
./file with space
sed 1s_
sed
1s_
一重引用符で囲まれた文字列の中に一重引用符で囲まれた文字列を入れようとしますが、これは不可能です。 2 番目の一重引用符が一重引用符で囲まれた文字列を終了します。'\''
リテラルを一重引用符で終わり、リテラルを一重引用符で囲み、リテラルを二重引用符で始めることができます。
find . -maxdepth 1 -name "* *" -exec bash -c 'sed '\''1s_ _o_'\'' <(echo $1)' h {} \;
もちろん、<(echo $1)
単一のスペースではなく、ワイルドカードまたは一連のスペースを含むファイル名は破損します。代わりに、なぜこのような記事を書いたのかわかりません<<<"$1"
。
答え2
私はこれがbashコマンドの一重引用符を閉じているからだと思います。-氏オプション。
bash
したがって、最初の引数-c
、2番目の引数sed 1s_
、3番目の引数_o_ <(echo $1)
などを実行しています。このように:
$ bash -c 'sed 1s_' '_o_ <(echo $1)'
3番目のパラメータ()はではなくに'_o_ <(echo $1)'
渡されます。bash
sed
コマンドを変更するには、パラメータに二重引用符を使用する必要がありますsed
。
$ find . -maxdepth 1 -name "* *" -exec bash -c 'sed "1s_ _o_" <(echo $1)' h {} \;