grep
Debian의 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
지시합니다 . 즉, 줄의 시작 부분에서 시작하거나 "단어가 아닌" 문자가 앞에 와야 하고 줄 끝에서 끝나거나 뒤따라야 함을 의미합니다. "비단어" 문자로.grep
fruit
그러나 매뉴얼 페이지에 따르면 "단어" 문자 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
구현에서는 -P
Perl과 유사한 정규식으로 전환하도록 선택할 수 있습니다.
perl
분명하다주위를 둘러보세요이전 또는 이후에 일치하는 항목이 있는지 확인하는 데 사용되는 연산자입니다.
grep -w word
grep -P '(?<!\w)word(?!\w)'
각각 및(?<!pattern)
(?!pattern)
부정적으로 되돌아보기그리고첫 번째운영자.
이것을 단어 구성 요소로 생각하려면 -
다음과 같이 변경할 수 있습니다.
grep -P '(?<![\w-])fruit(?![\w-])'
or 가 뒤에 오기 때문에 foo fruit bar
or 와 일치 foo/fruit/bar
하지만 일치 foo/fruit
하지 않습니다 .foo/fruit-bar
fruit
-
또는하지만 어떤 캐릭터라도/
:
grep -P '(?<![^/])fruit(?![^/])'
또는공백으로 구분된 단어:
grep -P '(?<!\S)word(?!\S)'
(여기서 \S
POSIX [^\s]
와 마찬가지로 [^[:space:]]
공백으로 분류되지 않은 문자입니다).