Grep: 별표(*)가 항상 작동하는 것은 아닙니다.

Grep: 별표(*)가 항상 작동하는 것은 아닙니다.

다음을 포함하는 문서를 grep하는 경우:

ThisExampleString

This*String... 또는 표현식의 경우 *String아무것도 반환되지 않습니다. 그러나 This*예상대로 위의 줄을 반환합니다.

표현식이 따옴표로 묶여 있는지 여부는 아무런 차이가 없습니다.

별표는 알 수 없는 문자 수를 나타내는 것이라고 생각했습니까? 표현식의 시작 부분에만 작동하는 이유는 무엇입니까? 이것이 의도된 동작이라면 This*String및 표현식 대신 무엇을 사용해야 합니까 *String?

답변1

별표정규 표현식"이전 요소와 0회 이상 일치"를 의미합니다.

의 특별한 경우에는 "이봐, grep, 일치하는 단어와 소문자를 0회 이상 연결한 다음 "라는 단어 grep 'This*String' file.txt를 입력하려고 합니다 . 소문자는 에서 찾을 수 없으므로 grep은 을 무시합니다 .ThisStringsExampleThisExampleString

의 경우 grep '*String' file.txt"grep, 단어 앞에 오는 빈 문자열(문자 그대로 아무 것도 없음)과 일치시키세요 String"라고 말하는 것입니다. 물론, 그렇게 ThisExampleString읽어서는 안 된다. (있다.다른 가능한 의미--플래그를 사용하거나 사용하지 않고 이것을 시도해 볼 수 있습니다 -E. 그러나 여기서 실제로 원하는 의미는 없습니다.)

이것이 "모든 단일 문자"를 의미한다는 것을 알면 .다음과 같이 할 수 있습니다 grep 'This.*String' file.txt. 이제 grep 명령은 이를 올바르게 읽습니다. This그 뒤에 문자(ASCII 문자 선택으로 생각)가 여러 번 반복되고 그 뒤에 가 옵니다 String.

답변2

*BRE 1 s, ERE 1 s 및 PCRE 1 s의 메타 문자는 이전에 그룹화된 패턴의 0개 이상의 발생(그룹화된 패턴이 *메타 문자 앞에 있는 경우), 이전 문자 클래스의 0개 이상의 발생(문자 클래스가 다음과 같은 경우)과 일치합니다. 메타 문자 앞에 있음 *) 또는 이전 문자가 0개 이상 발생합니다(그룹화된 패턴이나 문자 클래스가 *메타 문자 앞에 없는 경우).

이는 패턴에서 그룹화된 패턴이나 문자 클래스가 앞에 오지 않는 메타 문자 This*String이기 때문에 메타 문자가 이전 문자(이 경우 문자)의 0개 이상의 발생과 일치함을 의미합니다.**s

% cat infile               
ThisExampleString
ThisString
ThissString
% grep 'This*String' infile
ThisString
ThissString

임의의 문자가 0개 이상 일치하려면 .모든 문자와 일치하는 메타 문자가 0개 이상 일치해야 합니다.

% cat infile               
ThisExampleString
% grep 'This.*String' infile
ThisExampleString

BRE 및 ERE의 메타 문자 *는 항상 "탐욕적"입니다. 즉, 가장 긴 일치 항목과 일치합니다.

% cat infile
ThisExampleStringIsAString
% grep -o 'This.*String' infile
ThisExampleStringIsAString

이는 원하는 동작이 아닐 수도 있습니다. 그렇지 않은 경우 옵션 grep을 사용하여 의 PCRE 엔진을 켜고 메타 문자를 -P추가 할 수 있습니다. 이 메타 문자를 및 메타 문자 ?뒤에 넣으면 탐욕이 변경되는 효과가 있습니다.*+

% cat infile
ThisExampleStringIsAString
% grep -Po 'This.*?String' infile
ThisExampleString

1: 기본 정규식, 확장 정규식 및 Perl 호환 정규식

답변3

여기에서 찾은 설명 중 하나링크:

별표 " *"는 정규식에서 와일드카드와 같은 의미가 아닙니다. 이는 앞의 단일 문자 또는 [0-9]와 같은 표현에 적용되는 수정자입니다. 별표는 앞에 오는 항목과 0개 이상 일치합니다. 따라서 [A-Z]*대문자 없음을 포함하여 모든 수의 대문자와 일치하고 [A-Z][A-Z]*하나 이상의 대문자와 일치합니다.

답변4

*쉘로서 특별한 의미를 갖습니다.글로빙문자("와일드카드") 및 정규식메타 문자. 두 가지를 모두 고려해야 하지만,인용하다정규 표현식을 사용하면 쉘이 특수하게 처리하는 것을 방지하고 변경되지 않은 상태로 전달되도록 할 수 있습니다.grep. 하지만일종의개념적으로 유사하지만 *쉘에 대한 의미는 에 대한 의미와 상당히 다릅니다 grep.

첫 번째쉘은 *와일드카드로 취급됩니다.

당신은 말했다:

표현식이 따옴표로 묶여 있는지 여부는 아무런 차이가 없습니다.

이는 명령을 실행할 때 발생한 디렉터리에 어떤 파일이 있는지에 따라 다릅니다. 디렉터리 구분 기호가 포함된 패턴의 경우 /전체 시스템에 존재하는 파일에 따라 달라질 수 있습니다. 당신은 항상해야인용하다grep--and 에 대한 정규식작은따옴표일반적으로 가장 좋습니다.-~하지 않는 한당신은 괜찮다고 확신해요잠재적으로 놀라운 변화의 9가지 유형그렇지 않으면 쉘이 수행합니다~ 전에명령 을 실행합니다 grep.

쉘이 *그렇지 않은 문자를 만날 때인용됨, "0개 이상의 문자"를 의미하는 것으로 간주됩니다.그것을 포함하는 단어를 대체합니다.패턴과 일치하는 파일 이름 목록이 있습니다. (다음으로 시작하는 파일 이름은 .제외됩니다. 패턴 자체가 다음으로 시작하지 않는 한. 또는어쨌든 이를 포함하도록 쉘을 구성했습니다.) 이것은 다음과 같이 알려져 있습니다.글로빙--그리고 이름으로도파일 이름 확장그리고경로명 확장.

의 효과는 grep일반적으로 첫 번째로 일치하는 파일 이름이 정규 표현식으로 간주된다는 것입니다. 비록 인간 독자에게는 그것이 정규식이라는 것이 매우 분명하더라도~ 아니다정규 표현식을 의미합니다. glob에서 자동으로 나열된 다른 모든 파일 이름은 파일로 사용됩니다.내부에일치하는 항목을 검색합니다. (목록은 보이지 않습니다. 에 불투명하게 전달됩니다 grep.) 사실상 이런 일이 발생하는 것을 원하지 않을 것입니다.

그 이유는때때로문제가 되지 않습니다. 그리고 귀하의 특별한 경우에는 적어도지금까지, 그렇지 않았습니다. 그것은 *혼자 남겨질 것 입니다다음 사항이 모두 사실인 경우:

  1. 있었다아니요이름이 일치하는 파일. ...또는일반적으로 set -f또는 이와 동등한 set -o noglob. 그러나 이는 흔한 일이 아니며 아마도 당신이 그런 일을 했다는 것을 알고 있을 것입니다.

  2. *일치하는 파일 이름이 없을 때 기본 동작을 그대로 두는 쉘을 사용하고 있습니다 . 이것은 Bash의 경우입니다.아마사용하지만 모든 Bourne 스타일 쉘에서는 그렇지 않습니다. (예를 들어 널리 사용되는 셸 Zsh의 기본 동작은 glob에 대한 것입니다.(ㅏ)확장하거나(비)오류가 발생합니다.)...또는쉘의 동작을 변경했습니다. 수행 방법은 쉘마다 다릅니다.

  3. 너는 ..하지 않았다그렇지 않으면글로브를 다음으로 교체할 수 있도록 쉘에 지시했습니다.아무것도 아님일치하는 파일이 없을 때나 오류 메시지와 함께 실패할 수도 있습니다. Bash에서는 nullglob또는를 활성화하여 수행했을 것입니다.failglob 쉘 옵션, 각각.

때때로 #2와 #3에 의존할 수 있지만 #1에는 거의 의존할 수 없습니다. 현재 작동하는 따옴표가 없는 패턴이 있는 명령 grep은 다른 파일이 있거나 다른 위치에서 실행하면 작동이 중지될 수 있습니다.정규식을 인용하면 문제가 사라집니다.

그 다음에명령 은 수량자로 grep처리됩니다 .*

다른 답변은 다음과 같습니다.작성자: Sergiy Kolodyazhnyy그리고코스로--또한 이 질문의 이러한 측면을 다소 다른 방식으로 해결합니다. 따라서 아직 읽지 않은 분들은 이 답변의 나머지 부분을 읽기 전이나 읽은 후에 읽어 보시기 바랍니다.

*인용이 보장되어야 하는 grep으로 가정하면 grep다음을 의미하는 것으로 간주됩니다.그 앞에 있는 항목여러 번 발생할 수 있습니다, 정확히 한 번만 발생하는 것이 아니라. 여전히 한 번 발생할 수 있습니다. 아니면 전혀 존재하지 않을 수도 있습니다. 아니면 반복될 수도 있습니다. 에 어울리는 텍스트어느그 가능성 중 일치될 것입니다.

"항목"이란 무엇을 의미합니까?

  • 싱글성격. b리터럴과 일치하므로 b0 개 b*이상의 bs와 일치하므로 , , , 등과 ab*c일치합니다 .acabcabbcabbbc

    마찬가지로, 이후.모든 문자와 일치, .*0개 이상의 문자와 일치1, 따라서 , , , even 등과 a.*c일치합니다 .acakcahjglhdfjkdlgjdfkshlgcacccccchjckhcc또는

  • 캐릭터 클래스. or 와 일치 [xy]하므로 각각 이 or 인 0개 이상의 문자와 일치하므로 , , , , , , , , 등과 일치 합니다.xy[xy]*xyp[xy]*qpqpxqpyqpxxqpxyqpyxqpyyqpxxxqpxxyq

    이는 다음에도 적용됩니다.속기 형식\w, \W, \s및 와 같은 문자 클래스입니다 \S. \w모든 단어 문자와 일치 하므로 \w*0개 이상의 단어 문자와 일치합니다.또는

  • 그룹. \(bar\)는 0개 이상의 와 일치 하므로 , , , 등과 일치합니다 bar.\(bar\)*barfoo\(bar\)*bazfoobazfoobarbazfoobarbarbazfoobarbarbarbaz

    -E또는 -P옵션을 사용하면 grep정규식을 다음과 같이 처리합니다.오히려또는PCRE각각으로보다는브레( ), 그룹은 대신 으로 둘러싸여 있으므로 대신 및 대신을 \( \)사용합니다 .(bar)\(bar\)foo(bar)bazfoo\(bar\)baz

man grepgrep마지막에는 BRE 및 ERE 구문에 대해 합리적으로 접근 가능한 설명을 제공하고 시작 부분에는 허용되는 모든 명령줄 옵션을 나열합니다 . 나는 그 매뉴얼 페이지를 자료로 추천하고, 또한GNU Grep 문서그리고이 튜토리얼/참조 사이트(위의 여러 페이지에 연결했습니다).

테스트 및 학습을 위해 grep패턴을 사용하여 호출하는 것이 좋지만 파일 이름은 지정하지 않는 것이 좋습니다. 그런 다음 터미널에서 입력을 받습니다. 줄을 입력하세요. 다시 에코되는 줄은 패턴과 일치하는 텍스트가 포함된 줄입니다. 종료하려면 줄 시작 부분에서 Ctrl+를 누르면 입력 끝을 알립니다. (또는 대부분의 명령줄 프로그램에서처럼 +를 D누를 수도 있습니다 .) 예를 들면 다음과 같습니다.CtrlC

grep 'This.*String'

--color플래그 를 사용하면 grep특정 항목이 강조 표시됩니다.부속정규 표현식과 일치하는 행을 검색합니다. 이는 정규 표현식의 기능을 파악하고 정규 표현식을 실행한 후 원하는 것을 찾는 데 매우 유용합니다. 기본적으로 Ubuntu 사용자는 명령줄에서 grep --color=auto실행할 때 이 목적에 충분하도록 실행 되는 Bash 별칭을 갖고 있으므로 수동으로 grep전달할 필요조차 없습니다 --color.

1 따라서 .*정규식에서 *쉘 글로브의 의미를 의미합니다. 그러나 차이점은 grep일치 항목이 포함된 행을 자동으로 인쇄한다는 것입니다.어딘가에따라서 일반적으로 .*정규식의 시작이나 끝에는 필요하지 않습니다.

관련 정보