私は 回答 をAUの質問に投稿しましたが、_$@
_のパラメーター展開がsh
シェルでは機能しないことがわかりました。
_<infile xargs -d'\n' sh -c 'echo "${@%%/*}"' _
_
bash
では問題なく動作します。これはsh
シェルの予期された動作ですか、それで拡張をどのように実行できますか?
さらに、xargs
の_-n1
_オプションを使用すると、一度にコマンドに1行しか渡せないことを知っていますが、sh
が_$@
_:
_<infile xargs -d'\n' -n1 sh -c 'echo "${0%%/*}"'
_
infile
に含まれるもの:
_A1 /B1/C1
A 2/B2/C2
A3/B3/C3
_
うん、ダッシュはここでは役に立たないようです。厳密に言えば、${@%...}
は POSIXで指定されていない であるため、厳密に言えば、これは誤りではありません。
次の4種類のパラメーター拡張は、サブストリング処理を提供します。 [...]パラメータが '
#
'、 '*
'、または '@
'の場合、展開の結果は不定です。
奇妙なことですが、そのような展開で1つの位置パラメーターの終わりを変更すると、次のパラメーターが削除されるようです。しかし、それが実際に終わりを修正しないのでなければ、そうではありません:
$ dash -c 'set -- foo bar; printf "<%s>\n" "${@%o}";'
<fo>
$ dash -c 'set -- foo bar; printf "<%s>\n" "${@%x}";'
<foo>
<bar>
$ dash -c 'set -- foo bar doo; printf "<%s>\n" "${@%r}";'
<foo>
<ba>
Bash、ksh、およびZshはすべて、各位置パラメータを個別に処理することで"${@#...}"
および"${@%...}"
を処理するように見えます。
dash
の明らかな回避策は、一度に1つの引数を変更することだと思います。
for x in "$@"; do echo "${x%%/*}"; done
価値があるのは、$*
で使用される接頭辞と接尾辞の削除拡張の動作もシェルによって異なることです。 Bashとkshは最初にパラメーターを変更し、その後それらを結合するようですが、Zshとdashは最初にパラメーターを結合し、連結文字列を変更します。
$ zsh -c 'set -- ax bx; printf "<%s>\n" "${*%%x*}";'
<a>
$ bash -c 'set -- ax bx; printf "<%s>\n" "${*%%x*}";'
<a b>