`a [bc] d` (괄호)와`a {b, c} d` (중괄호)의 차이점은 무엇입니까?


28

차이점은 무엇이며 a[bc]d그리고 a{b,c}d? 사람들 a{b,c}d이 이미있을 때 왜 사용 a[bc]d합니까?


누가 사용하라고 command a[bc]d했습니까?
Jesse_b

3
올바르게 이해하면 분명히 사용됩니다.
Weijun Zhou

7
두 사람 사이의 혼란이 어떻게 발생했는지 이해하지 못하는 것 같습니다.
Jesse_b

최근에는 아니지만 Linux에 익숙하지 않은 동료가 명시 적으로 요청했습니다.
Weijun Zhou

@Jesse_b 같은 파일에서 작업을 ls시도하고 단일 문자 만 시도하면 동일한 방식으로 작동합니다.
Nacht-

답변:


43

둘은 상당히 다릅니다.

a[bc]dA는 파일 이름 패턴 (이외의 껍질에이 fish). 그것은 두 가지로 확대 될 파일 이름 abdacd그 경우 현재 디렉토리에 존재하는 파일의 이름입니다.

  • [...]부분은 상장 (또는 범위가 포함될 때 요소를 조합) 사람에서 단일 문자와 일치하는 괄호 표현이다. 패턴과 일치 시키려면 a[bc]d문자열 ad파일 이름 사이의 문자는 a b또는 a 여야합니다 c.

  • 경우는 abd존재하지만 acd, 그것은 단지로 확장 할하지 않는 abd반대, 그리고 그.

  • 둘 경우 abd,도 acd존재 쉘 및 옵션에 따라, 그것은 오류를 트리거하지 않습니다 (원래 유닉스 것 sh, (t)csh, zsh, fish, bash -O failglob) 가능성이 쉘을 종료하거나 (Bourne의 같은과 패턴 unexpanded¹을 남겨 rc-like 껍질) 이상으로 확장 아무것도 ( bash/zsh/yash -o nullglob, 일부 이전 버전의 fish원래 Unix sh(t)csh동일한 명령에 다른 일치하는 glob가있는 경우).

a{b,c}dA는 중괄호 확장 (이들을 지원 포탄은). 그것은 두 가지로 확대 될 문자열 abdacd.

  • {...}(일부 쉘에, 또한 등의 범위 일 수있다 본 실시 예에서 부분 문자열 쉼표로 구분 세트이다 a..k또는 20..25추천 이상의 고급 것들 00..20..2또는 0..20..2%02d)와 팽창 측부 이러한 스트링의 각각의 조합에 의해 계산된다 문자열 ad. 이 문자열은 단일 문자보다 길 수 있으며 확장 확장 자체 일 수도 있습니다.

  • 확장은 이러한 문자열이 기존 파일 이름에 해당하는지 여부에 관계없이 발생합니다.

문자열을 구성하는 경우 중괄호 확장을 사용하십시오. 파일 이름이 일치하는 경우 파일 이름 패턴을 사용하십시오.


¹이 특별한 경우에 a[bc]d기존 파일의 이름이 될 수 있습니다. 이런 rm -f ./*.[ch]쉘에서 사용하는 것이 위험 rm -f ./*.{c,h}하고 문제가 적은 이유 입니다.


"abd가 있지만 acd가 없으면 abd로만 확장됩니다"를 설명해 주셔서 감사합니다. 나는 그것이 내 대답에서 빠진 것 같아요.
Weijun Zhou

9
또 다른 중요한 차이점은에서이다 a{b,c}dbc부품이 하나의 문자가 될 필요가 없습니다; 예 ex{ten,ci}sion. 반면 ex[tenci]sion않거나 일치 어떤 이 편지를.
Alexis

7

a[bc]d패턴 매칭 및 POSIX 표준의 일부이다. POSIX에서는 "패턴 괄호 표현"으로 소개되었습니다. 설명서의 섹션 2.13에 설명되어 있습니다.

인용 부호가없고 대괄호 표현식 외부에서 다음 세 문자는 패턴 지정에서 특별한 의미를 갖습니다.

    ?
      물음표는 모든 문자와 일치하는 패턴입니다.
    *
      별표는 여러 문자와 일치하는 패턴에 설명 된대로 여러 문자와 일치하는 패턴입니다.
    [
      열린 브래킷은 패턴 브래킷 표현을 도입해야합니다.

섹션 2.13.3은 파일 이름 확장에 사용될 때 일반적인 정규 표현식에 대해 예상되는 것과 다르게 행동하는 것을 언급합니다 (강조)

지금까지 단일 문자와 일치하는 패턴 및 여러 문자와 일치하는 패턴에서 설명한 규칙은 파일 이름 확장에 패턴 일치 표기법을 사용할 때 적용되는 다음 규칙에 따라 규정됩니다.

경로명의 슬래시 문자는 패턴에 하나 이상의 슬래시를 사용하여 명시 적으로 일치해야합니다. 별표 또는 물음표 특수 문자 나 대괄호 표현식과 일치하지 않아야합니다. 패턴의 슬래시는 대괄호 표현식 전에 식별해야합니다. 따라서 파일 이름 확장에 사용되는 패턴 괄호 표현식에는 슬래시를 포함 할 수 없습니다. 대응하는 닫는 대괄호를 찾기 전에 이스케이프 처리되지 않은 열린 대괄호 문자 뒤에 슬래시 문자가있는 경우, 열린 대괄호는 일반 문자로 취급됩니다. 예를 들어, 패턴은 "a[b/c]d"같은 경로 이름과 일치하지 않습니다 abd또는 a/d. 문자 그대로 경로 이름 만 일치합니다 a[b/c]d.

a{b,c}d중괄호 확장 이며 POSIX의 사양에 없습니다. 다음은 bash 매뉴얼 의 해당 부분입니다 (강조 표시).

중괄호 확장은 임의의 문자열을 생성 할 수 있는 메커니즘 입니다. 이 메커니즘은 파일 이름 확장 과 유사 하지만 (파일 이름 확장 참조) 생성 된 파일 이름이 없어도됩니다 . 괄호 확장 패턴은 선택적 프리앰블 의 형태를 취한 후 일련의 쉼표로 구분 된 문자열 또는 한 쌍의 괄호 사이의 시퀀스 표현식과 선택적 포스트 스크립트가 뒤 따릅니다 . 프리앰블은 중괄호 안에 포함 된 각 문자열에 접두사가 붙은 다음 포스트 스크립트가 각 결과 문자열에 추가되어 왼쪽에서 오른쪽으로 확장됩니다.

@mosvy의 의견에 따르면, 이것은 처음부터 나타 csh났지만 동작 bashcsh다른 쉘과 다릅니다 . 이 유형의 괄호 확장도에 glob(3)있습니다.

3.0 {a..z}후에 만 나타나는 다른 유형의 중괄호 확장 이 bash있으며 bash4.0에 더 추가됩니다 .

globbing이 켜진 쉘에서 빈 폴더에서 실행하면 다음 결과가 반환됩니다.

$ echo a[bc]d
a[bc]d
$ echo a{b,c}d
abd acd

@Jesse_b의 의견에 따라 대화 형 쉘에 있고 두 가지 모두 적용되는 경우 a[bc]d입력하는 데 어려움이 없습니다. 예를 들면 grep pattern [ab][12].txt.


2
중괄호 확장은 "bashism"이 아닙니다. 그것은 csh오래 전에 처음 등장했습니다 bash. glob (3) 라이브러리 함수에도 있습니다. 차이점은 bash다른 확장 전에 수행 a=A; ab=A/B; ac=A/C; echo $a{b,c}된다는 것입니다. 다른 쉘과는 다르게 bash에서 작동합니다.
mosvy

고맙습니다. 답변을 업데이트하겠습니다.
Weijun Zhou
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.