더 나은 선택.

더 나은 선택.

와일드카드와 중괄호 안에 지정된 확장자 세트가 포함된 문자열을 확장하려고 합니다. 아래 예에서 볼 수 있듯이 아무 효과도 없는 것 같습니다. 변수는 firstList잘 확장되지만, secondList또는 은 올바르게 확장 thirdList되지 않습니다 fourthList. 나는 또한 다양한 버전을 시도했지만 eval그 중 아무것도 작동하지 않습니다. 어떤 도움이라도 대단히 감사하겠습니다.

#!/bin/bash
touch a.ext1
touch b.ext1
firstList='*.ext1'
ls  $firstList
touch a.ext2
touch b.ext2
secondList='*.{ext1,ext2}'
ls $secondList 
ls '$secondList'
ls "$secondList"
thirdList=*.{ext1,ext2}
ls $thirdList  
ls '$thirdList'
ls "$thirdList"
fourthList="*.{ext1,ext2}"
ls $fourthList
ls '$fourthList'
ls "$fourthList"

답변1

이것껍데기확장은 인용되지 않은 경우에만 발생합니다 *. 인용하면 쉘이 확장되지 않습니다.

또한 셸에서 확장하려면 중괄호 확장을 인용 해제해야 합니다.

이것은 작동합니다(Echo를 사용하여 쉘이 무엇을 하는지 살펴보겠습니다).

$ echo *.{ext1,ext2}
a.ext1 b.ext1 a.ext2 b.ext2

다른 이름의 파일이 존재하는 경우에도:

$ touch {a,b}.{ext1,ext2} {c,d}.{ext3,ext4} none
ls
a.ext1  a.ext2  b.ext1  b.ext2  c.ext3  c.ext4  d.ext3  d.ext4  none

$ echo *.{ext1,ext2}
a.ext1 b.ext1 a.ext2 b.ext2

이것이 작동하는 이유는 무엇입니까?

그것이 왜 작동하는지 이해하는 것이 중요합니다. 이는 확장 순서 때문입니다. 먼저 "중괄호 확장"이 있고 마지막으로 "경로 이름 확장"(일명 glob 확장)이 있습니다.

Brace --> Parameter (variable) --> Pathname

"경로 이름 확장"을 일시적으로 끌 수 있습니다:

$ set -f
$ echo *.{ext1,ext2}
*.ext1 *.ext2

"경로 이름 확장"은 *.ext1및 의 두 가지 매개변수를 사용합니다 *.ext2.

$ set +f
$ echo *.{ext1,ext2}
a.ext1 b.ext1 a.ext2 b.ext2

문제는 변수를 사용하여 중괄호 확장을 수행할 수 없다는 것입니다.
이건 이전에도 여러번 설명했었죠"분기 확장"에서 변수 사용

"변수 확장"의 결과인 "중괄호 확장"을 확장하려면 를 사용하여 명령줄을 셸에 다시 제출해야 합니다 eval.

$ list={ext1,ext2}
$ eval echo '*.'"$list"

지원 -->바꾸다--> 글로벌|-->지원하다-->변수-->전반적인 상황
........여기에 인용-->^^^^^^ ||평가^^^^^^^^^^^^^^^^^^^^^^^^^^

파일 이름 값은 평가 실행 문제를 일으키지 않습니다.

$ touch 'a;date;.ext1'
eval echo '*.'"$list"
a;date;.ext1 a.ext1 b.ext1 a.ext2 b.ext2

그러나 그 가치는 $list안전하지 않을 수 있습니다. 그러나 값은 $list스크립트 작성자가 설정합니다. 스크립트 작성자는 다음을 제어할 수 있습니다 eval. 단지 외부에서 설정된 값을 사용하지 않는 것뿐입니다 $list. 이 시도:

#!/bin/bash
touch {a,b,c}.ext{1,2}
list=ext{1,2}
eval ls -l -- '*.'"$list"

더 나은 선택.

(평가 없이) 또 다른 옵션은 다음과 같습니다.Bash "확장 모드" 사용:

#!/bin/bash
shopt -s extglob
list='@(ext1|ext2)'
ls -- *.$list

참고: 두 솔루션(평가 및 패턴)(작성된 대로)은 공백이나 줄 바꿈이 있는 파일 이름에 안전합니다. 그러나 따옴표가 없거나 eval이 따옴표를 제거하기 $list때문에 공백이 있는 경우에는 실패합니다 .$list

답변2

고려하다:

secondList='*.{ext1,ext2}'
ls $secondList 

문제는버팀대 확장이미 마쳤어앞으로 변수 확장. 이는 위의 경우 버팀대 확장이 수행되지 않음을 의미합니다.

이는 bash가 명령줄을 처음 볼 때 중괄호가 없기 때문입니다. 확장 후에 secondList는 너무 늦을 것입니다.

다음이 작동합니다:

$ s='*'
$ ls $s.{ext1,ext2}
a.ext1  a.ext2  b.ext1  b.ext2

여기서 명령줄에는 다음과 같이 중괄호가 있습니다.버팀대 확장첫 번째 단계로 수행할 수 있습니다. 그 후, $s(의 값을 대체합니다.변수 확장) 드디어경로명 확장처형되다.

문서

man bash확장 순서를 설명하세요.

확장 순서는 중괄호 확장, 매개변수 및 변수 확장, 산술 확장, 명령 대체(왼쪽에서 오른쪽으로 수행됨)입니다.

관련 정보