"grep -w"가 하이픈/빼기 기호("-")가 뒤에 오는 단어와 일치하는 이유는 무엇입니까?

"grep -w"가 하이픈/빼기 기호("-")가 뒤에 오는 단어와 일치하는 이유는 무엇입니까?

grepDebian의 Bash 스크립트에서 명령을 사용하는 방법 에 대해 질문하고 싶습니다 .

다음 줄이 포함된 샘플 파일이 있습니다.

/fruit-/apple.txt
/fruit-/banana.txt
/fruit-/samples
/vegetables-/carrot.txt
/vegetables-/garlic.txt

word 가 포함된 모든 줄을 선택하고 싶습니다 fruit-.

다음 명령을 호출할 수 있습니다.

grep -w "fruit-" file.txt

출력은 다음과 같습니다:

/fruit-/apple.txt
/fruit-/banana.txt
/fruit-/samples

하지만 다음 명령을 사용할 때:

grep -w "fruit" file.txt

또한 위와 동일한 출력을 얻습니다. 그러나 이것은 잘못된 것입니다. 출력은 0이어야 합니다. 입력 모드가 없기 때문입니다 -.

왜 제대로 grep치료 하지 않습니까 -?

답변1

이 옵션은 "단어"와 일치하는 줄만 찾도록 -w지시합니다 . 즉, 줄의 시작 부분에서 시작하거나 "단어가 아닌" 문자가 앞에 와야 하고 줄 끝에서 끝나거나 뒤따라야 함을 의미합니다. "비단어" 문자로.grepfruit

그러나 매뉴얼 페이지에 따르면 "단어" 문자 grep는 다음과 같습니다.

단어를 구성하는 문자는 문자, 숫자, 밑줄입니다.

-이는 "비단어" 문자를 의미하며 일치 알고리즘이 도착 시 중지되므로 fruit-"단어 검색"과 일치합니다 .fruit-

이제 처음 두 행 사이에 내용이 있는 행만 선택하려는 것 같습니다./ 정확히 fruit, 상대적패턴이 포함되어 있습니다. fruit. 이러한 경우 일치 항목을 보다 명확하게 만들어야 합니다.

  • 를 사용하면 grep다음과 같이 말할 수 있습니다.
    grep "^/fruit/" file.txt
    
    이렇게 하면 패턴이 줄의 시작 부분에 고정되고 -그 뒤에 오지 않는 줄만 허용됩니다 fruit.
  • 또는 awk컬렉션을 /필드 구분자로 사용하세요.
    awk -F/ '!$1&&$2=="fruit"' file.txt
    
    /첫 번째 필드가 비어 있고(즉, a로 시작 ) 두 번째 필드가 정확히 인 행만 허용됩니다 fruit.

답변2

@AdminBee무엇인지 명확히 했습니다단어의미 grep, 이 맥락에서 단어의 다른 정의를 사용하도록 지시하는 방법을 추가하겠습니다.

grep -w word다소 word앞이나 뒤에 단어 문자가 없는 s를 찾습니다.

일부 grep구현에서는 -PPerl과 유사한 정규식으로 전환하도록 선택할 수 있습니다.

perl분명하다주위를 둘러보세요이전 또는 이후에 일치하는 항목이 있는지 확인하는 데 사용되는 연산자입니다.

grep -w wordgrep -P '(?<!\w)word(?!\w)'각각 및(?<!pattern)(?!pattern)부정적으로 되돌아보기그리고첫 번째운영자.

이것을 단어 구성 요소로 생각하려면 -다음과 같이 변경할 수 있습니다.

grep -P '(?<![\w-])fruit(?![\w-])'

or 가 뒤에 오기 때문에 foo fruit baror 와 일치 foo/fruit/bar하지만 일치 foo/fruit하지 않습니다 .foo/fruit-barfruit-

또는하지만 어떤 캐릭터라도/:

grep -P '(?<![^/])fruit(?![^/])'

또는공백으로 구분된 단어:

grep -P '(?<!\S)word(?!\S)'

(여기서 \SPOSIX [^\s]와 마찬가지로 [^[:space:]]공백으로 분류되지 않은 문자입니다).

관련 정보