ZSH에서 문자열 값에서 배열로 중괄호 확장을 수행합니다.

ZSH에서 문자열 값에서 배열로 중괄호 확장을 수행합니다.

다음 스니펫에 설명된 상황을 고려하면 다음과 같습니다.

# Input string provided as function argument:
input='base/{local,remote,other}$(echo hi)'
# Desired result from performing just brace expansion of the above:
expected=('base/local$(echo hi)' 'base/remote$(echo hi)' 'base/other$(echo hi)')

ZSH에서 이를 수행하는 올바른 방법은 무엇입니까?오직임의의 사용자 정의 입력 문자열을 중괄호로 확장하고 결과 매개변수 배열을 다른 변수에 저장하시겠습니까? 값의 중괄호 확장을 강제로 찾은 유일한 방법은 eval?를 사용하는 것입니다. 그래서 내가 요구하는 것이 가능한지 궁금합니다.

일부 연구에서는 다음이 효과가 있을 수 있다고 제안하지만 실제로는 그렇지 않은 것 같습니다.

expanded=(${^input})
# Results in: expanded=('base/{local,remote,other}$(echo hi)')

답변1

다른 형태의 확장이 아닌 쉘 코드에서 찾을 수 있는 것처럼 확장을 수행하려면 연산자가 없으므로 , , 뒤에 를 eval제외한 모든 항목을 인용하는 것과 같은 방법을 사용해야 합니다 . 그리고 .{},

어쩌면 다음과 같은 것일 수도 있습니다.

set -o extendedglob
eval "expanded=( ${input//(#m)[^{\},]##/${(qq)MATCH}} )"

(따옴표가 있어도 {1..5}활성화된 경우 ..처럼 여전히 확장되는 것처럼 보입니다.)-{a-f}braceccl

a\{x,y}위의 내용은 이스케이프, 확장을 처리하지 않습니다 a\x a\y및 .a"{x,y}"a"x" a"y"

참고로 bracexpand이 옵션이 활성화되어 있고 noglob이 옵션이 활성화되지 않은 경우(mksh 및 ksh93 최신 버전의 기본값) ksh는 인용되지 않은 인수 확장 또는 명령 대체에 대해 중괄호 확장을 수행합니다.

ksh93의 경우 와일드카드를 비활성화하는 또 다른 방법은 로 설정하는 것입니다 FIGNORE. *따라서 ksh93에서는 다음을 수행할 수 있습니다.

IFS= FIGNORE=*
expanded=( $input )

답변2

% x='{huh,what}'
% foo=( .(e:"reply=($x)":) )
% print -Rl $foo
huh
what

글쎄, 그것은 아마도 너무 영리한 것 같습니다. 왜냐하면 그것은 eglob 평가자를 남용하여 (무시된) glob 결과를 보간 중괄호 확장으로 대체하기 때문입니다.

관련 정보