shシェルは$ @でパラメータ拡張をサポートしていませんか?

shシェルは$ @でパラメータ拡張をサポートしていませんか?

出版しました回答AUに関する質問に関しては、パラメータ拡張がシェル$@で機能しないことがわかりました。sh

<infile xargs -d'\n' sh -c 'echo "${@%%/*}"' _

しかし、動作しますbash。これがシェルの期待される動作ですかsh?そこで拡張をどのように実行しますか?

-n1また、オプションはxargs一度に1行だけコマンドに渡すことができることを知っていますが、shこれを拡張できるかどうかに興味があります$@

<infile xargs -d'\n' -n1 sh -c 'echo "${0%%/*}"'

infile含む:

A1 /B1/C1
A 2/B2/C2
A3/B3/C3

答え1

はい、ここではダッシュがあまり役に立たないようです。間違った言葉では${@%...}ありませんが、厳密に言えば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とダッシュは最初にパラメータを連結してから連結文字列を変更します。

$ zsh -c 'set -- ax bx; printf "<%s>\n" "${*%%x*}";'
<a>
$ bash -c 'set -- ax bx; printf "<%s>\n" "${*%%x*}";'
<a b>

関連情報