Bash의 와일드카드 역사

Bash의 와일드카드 역사

Bash "와일드카드"와 정규 표현식이 동일하지 않은 역사적인 이유가 있습니까? 예를 들어, Bash에서는 [1-2]*1 또는 2로 시작하고 그 뒤에 다른 것이 오는 모든 항목과 일치하는 반면 정규식은 [1-2]*1과 2의 시퀀스만 일치한다고 믿습니다 . 내 Bash 스크립트와 REGEX foo는 모두 약하고 이러한 차이점과 관련된 문제에 자주 직면하므로 왜 다른지 궁금합니다.

답변1

bashksh원래 일부 대화형 기능을 갖춘 csh/tcsh의 부분 복제로 1980년대 후반에 설계되었습니다.

와일드카드의 출처는 해당 와일드카드가 내장된 초기 쉘에서 찾아야 합니다.

ksh그 자체는 Bourne 쉘의 확장입니다. Bourne 쉘 자체(1979년 Unix V7에서 처음 출시됨)는 처음부터 깔끔하게 구현되었지만 Thompson 쉘(V1 -> V6 쉘)에서 완전히 벗어나지는 않고 Mashey 쉘의 기능을 병합합니다.

특히 명령 매개변수는 여전히 공백으로 구분되어 있으며 |새로운 파이프 연산자가 있지만 ^여전히 대안으로 지원됩니다( [!a-z]이 작업을 수행하고 수행하지 않는 이유에 대한 설명도 있음 [^a-z]). $1스크립트의 첫 번째 매개변수 및 그 반대 슬래시는 여전히 이스케이프 문자입니다. 많은 정규식 연산자( ^\|$)는 셸에서 고유한 특별한 의미를 갖습니다.

Thompson 쉘은 와일드카드 지정을 위해 외부 유틸리티를 사용합니다. sh따옴표가 없는 *, 또는 s 가 command 에서 발견되면 [해당 명령이 실행됩니다.?glob

rm *.txt

궁극적으로 다음과 같이 glob을 실행하게 됩니다.

["glob", "rm", "*.txt"]

glob은 결국 rm패턴과 일치하는 파일 목록을 통해 실행됩니다.

grep a.\*b *.txt

다음과 같이 실행됩니다 glob:

["glob", "grep", "a.\252b", "*.txt"]

*glob위의 내용은 문자 가 와일드카드로 처리되는 것을 방지하기 위해 문자에 비트 8을 설정하여 인용되었습니다 . glob이 비트는 통화 전에 제거됩니다 grep.

정규식을 사용하여 동일한 작업을 수행하려면 다음과 같습니다.

regexp rm '\.txt$'

또는:

regexp rm '^[^.].*\.txt$'

도트 파일을 제외합니다.

이스케이프 연산자는 쉘 특수 문자로도 사용되기 때문에 필요하며 .정규식 연산자가 파일 이름에 흔히 사용된다는 사실로 인해 일치하는 파일 이름이 초보자에게 덜 적합하고 복잡해집니다. 대부분의 경우 필요한 것은와일드카드?하나( ) 또는 임의의 숫자( ) 문자를 바꿀 수 있습니다 *.

이제 다른 쉘은 다른 와일드카드 문자를 추가합니다. 오늘날 ksh 및 zsh glob( bash -O extglobksh glob의 하위 집합을 어느 정도 구현함)은 기능적으로 정규식과 동일하며, 파일 이름 및 현재 셸 구문과 함께 사용하기가 덜 번거로운 구문을 사용합니다. 예를 들어 zsh(확장된 전역 확장 사용)에서는 다음을 수행할 수 있습니다.

echo a#.txt

(가능성이 낮은) 일치 항목을 더 쉽게 만들고 싶다면 a.than .txtecho (^a*\.txt$)사용하세요(여기서 중괄호는 셸 연산자에서 정규식 연산자를 분리하는 방법으로 사용됩니다. 이는 아마도 셸에서 처리하는 방식일 것입니다).

echo (foo|bar|<1-20>).(#i)mpg

기본 이름이 foo, bar 또는 1~20의 십진수(대소문자 구분 안 함)인 mpg 파일의 경우...

ksh93이제 정규 표현식(기본, 확장, Perl 유사 또는 "향상된")을 glob에 통합하는 것도 가능하며(비록 버그가 많지만) glob과 regexp( printf %R, printf %P) 사이를 변환하기 위해 제공되는 도구도 있습니다.

echo ~(Ei:.*\.txt)

(숨겨지지 않은) txt 파일 일치두번째확장 정규식, 대문자 및 소문자무감각하게.

답변2

정규 언어소개받다클라인1956. 이 중요한 논문에는 완전한 현대 정규식 표기법이 없지만 A*"반복 횟수 A"를 의미하는 "Kleen star"를 소개했습니다. 다음 10년 동안 특히 .임의의 문자에 대해 그리고 ?이전 문자가 선택 사항임을 나타내기 위해 다소간 표준 기호가 많이 등장했습니다 .

Bash의 와일드카드 기호는 다음에서 파생됩니다.glob주문하다처음부터 끝까지 소개유닉스 v11971. 당시에는 별도의 프로그램에서 와일드카드를 수행했지만 나중에 셸로 이동했습니다. 이전 명령은 "모든 문자"와 "모든 문자 시퀀스"를 의미 glob해야 했습니다 . 왜 이러한 역할이 선택되었는지는 알 수 없습니다. 아마도 정규식에서 영감을 받은 것 같습니다.?*?*

와일드카드는 정규식만큼 일반적으로 사용되도록 의도되지 않았으며 당시 정규식은 그다지 일반적이지 않았으므로 이러한 개념을 통합할 필요가 없었습니다. 처음부터 파일명 패턴과 정규식에서 , ?, .가 서로 다른 의미를 갖는 구문 비호환성이 있었습니다.*

bash와 같은 최신 셸은 glob 모드를 확장하지만 이전 버전과의 호환성을 유지하기 위해 점진적으로 발전했습니다. Ksh88(1988년 버전)코헨 쉘)은 일반적인 정규식 구문과 다르지만 *(PATTERN)반복 횟수를 나타내는 것 PATTERN, @(PATTERN1|PATTERN2)" PATTERN1또는 PATTERN2" 등을 나타내는 것 등에서 크게 영감을 받은 쉘 패턴에 대한 확장된 구문을 소개합니다.

최신 버전의 bash(2.02부터)는 명령을 먼저 실행하면 ksh88의 확장 모드를 지원합니다 shopt -s extglob.

답변3

역사적 이유: 그렇습니다. 인용하다:
http://en.wikipedia.org/wiki/Glob_(프로그래밍)#Origin

차이점을 보여주기 위해 다음은 훌륭하고 간단한 예입니다.a*

  • 쉘 와일드카드: 첫 번째 문자는 이고 a그 다음은 아무 문자(a, ab, abca...)입니다.
  • 정규식: 문자가 0번 이상 반복된다는 의미입니다 a(a, aa, aaa...).

나는 이러한 의미의 차이가 새로운 사용자에게 매우 혼란스럽다는 점에 쉽게 동의합니다.

와일드카드는 초보자가 익히기 더 쉬울 수 있지만 강력하지도 않습니다.

관련 정보