나는 출판했다답변AU에 대한 질문과 관련하여 매개변수 확장이 셸 $@
에서 작동하지 않는다는 것을 발견했습니다.sh
<infile xargs -d'\n' sh -c 'echo "${@%%/*}"' _
하지만 작동합니다 bash
. 이것이 쉘의 예상된 동작입니까 sh
? 거기서 확장을 어떻게 수행합니까?
-n1
또한 옵션을 통해 xargs
한 번에 한 줄만 명령에 전달할 수 있다는 것을 알고 있지만 sh
이것이 확장될 수 있는지에 관심이 있습니다 $@
.
<infile xargs -d'\n' -n1 sh -c 'echo "${0%%/*}"'
infile
포함하다:
A1 /B1/C1
A 2/B2/C2
A3/B3/C3
답변1
네, 여기서는 대시가 그다지 유용하지 않은 것 같습니다. 틀린말은 ${@%...}
아니지만 엄밀히 말하면POSIX가 지정되지 않았습니다.:
다음 네 가지 매개변수 확장은 하위 문자열 처리를 제공합니다. [...] 인수가 "
#
", "*
" 또는 "@
"인 경우 확장 결과는 지정되지 않습니다.
그러나 이것은 이상합니다. 그러한 확장이 하나의 위치 매개변수의 끝을 수정하면 다음 위치 매개변수를 제거하는 것 같습니다. 그러나 실제로 결말을 수정하지 않는 경우에는 그렇지 않습니다.
$ 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
한 번에 하나의 매개변수를 수정하는 것입니다.
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>