"eval" 없이 {} 확장에서 변수를 사용할 수 있나요?

"eval" 없이 {} 확장에서 변수를 사용할 수 있나요?

{}를 유치하지 않고 확장 프로그램에서 변수를 사용할 수 있나요 eval? 그렇다면 어떻게 해야 할까요?

이것은 작동하지 않습니다:

$ touch 1.foo 1.bar
$ ls 1.{foo,bar}
1.bar  1.foo
$ extensions=foo,bar
$ ls 1.{$extensions}
ls: cannot access 1.{foo,bar}: No such file or directory

적용 대상 eval:

$ eval ls 1.{$extensions}
1.bar  1.foo

답변1

지원 확장이 매우 일찍 이루어짐확장(사실 가장 먼저) 변수 확장 전입니다. 변수 확장 결과에 대해 중괄호 확장을 수행하려면 를 사용해야 합니다 eval.

evalextensions중괄호 패턴 대신 와일드카드 패턴을 사용하면 동일한 효과를 얻을 수 있습니다. extglob활성화 옵션 설정ksh와 유사한 모드.

shopt -s extglob
extensions='@(foo|bar)'
ls 1.$extensions

답변2

중괄호 안에 변수를 확장하는 방법은 다음과 같습니다.평가 없음:

end=3
declare -a 'range=({'"1..$end"'})'

이제 멋진 숫자 배열이 생겼습니다.

for i in ${range[@]};do echo $i;done
1
2
3

bash 4.3.11에서 테스트되었지만 모든 최신 버전에서 작동합니다.

답변3

Bash 및 기타 쉘에서 사용할 수 있는 또 다른 기술은 배열을 사용하는 것입니다.

$ extensions=(foo bar)
$ ls "${extensions[@]/#/1.}"

이것이 매개변수 확장의 (패턴 대체) 형태입니다. (불행히도 이 역시 POSIX 규격이 아닙니다.) 배열의 각 요소에 대체를 적용하고 요소 간 분리를 유지하도록 지정합니다. 안에${parameter/pattern/string}[@]#무늬문자열은 ^정규 표현식(즉, 대부분의 대체)에서처럼 작동합니다. 이는 대체가 매개변수 값의 시작 부분에서만 발생할 수 있음을 의미합니다. 그래서s/old/new/

$ ls "${extensions[@]/#/1.}"

동등하다

$ ls "${확장자[0]/#/1.}" "${확장자[1]/#/1.}"

(이 배열에는 인덱스 0과 1의 두 요소가 있으므로) 다음으로 확장됩니다.

$ ls "1.foo" "1.bar"

인용하다

"확장"에 따옴표가 필요한 경우, 즉 (아마도) 공백이나 경로 이름 확장(와일드카드/와일드카드) 문자가 포함되어 있는 경우 따옴표가 중요합니다. 예를 들어,

$ extensions=("foo bar" "*r")

그 다음에

$ ls ${extensions[@]/#/1.}

(따옴표 제외)는 다음으로 확장됩니다.

$ ls 1.foo bar 1.*r

(여기서 1.foobar는 별도의 인수입니다), 이는 차례로 다음으로 확장됩니다.

$ ls 1.foo bar 1.anteater 1.bar 1.bear 1.cougar 1.deer 1.grasshopper …

( 1.*r따옴표가 없는 와일드카드이기 때문입니다.) 인용의 중요성에 대한 자세한 내용은 다음을 참조하세요.bash/POSIX 쉘에서 변수를 인용하는 것을 잊어버리는 보안 위험.

문자열의 끝을 일치시킬 수도 있습니다.%에서 사용하여무늬:

$ fnames=(cat dog)
$ ls "${fnames[@]/%/.c}"

다음으로 확장

$ ls "cat.c" "dog.c"

하지만 조심하세요:% 아니요$정규식과 동일한 방식으로 작동합니다. 꼭 넣어야 해시작~의무늬 매개변수 값의 끝에서 한계 일치가 발생합니다. 예를 들어 다음과 같은 경우

$ fnames=(cat.c dog.c)

당신은 얻고 싶어 cat.o하고 dog.o, 하지 마세요 "${fnames[@]/.c%/.o}"--이것은 작동하지 않습니다. 하다

$ ls "${fnames[@]/%.c/.o}"

하지만 그렇게 하지 마세요 "${fnames[@]/.c/.o}"(완전히 무시하세요 %). "fnames" 중 하나가 이면 다음 dog.catcher.c으로 변환됩니다(왜냐하면dog.oatcher.c첫 번째 .c) 로 대체됩니다 .o.

안타깝게도 접두사와 접미사를 쉽게 추가할 수 있는 방법은 없습니다.

$ ls 1.{foo,bar}.c

변수, 배열 및 이에 적용될 수 있는 변환에 대한 자세한 내용은 bash 설명서를 참조하세요.

관련 정보