grep은 지정된 그룹과 일치하는 출력만 출력할 수 있습니까?

grep은 지정된 그룹과 일치하는 출력만 출력할 수 있습니까?

파일이 있다고 가정해 보겠습니다.

# file: 'test.txt'
foobar bash 1
bash
foobar happy
foobar

"foobar" 뒤에 어떤 단어가 오는지 알고 싶어서 다음 정규식을 사용할 수 있습니다.

"foobar \(\w\+\)"

괄호는 내가 foobar 다음의 단어에 특히 관심이 있다는 것을 나타냅니다. 하지만 을 수행하면 grep "foobar \(\w\+\)" test.txt"foobar 뒤의 단어"뿐만 아니라 전체 정규식과 일치하는 전체 줄을 얻습니다.

foobar bash 1
foobar happy

나는 명령의 출력이 다음과 같기를 원합니다.

bash
happy

정규식의 그룹화(또는 특정 그룹화)와 일치하는 항목만 출력하도록 grep에 지시하는 방법이 있습니까?

답변1

GNU grep에는 -PPerl 스타일 정규식 옵션과 -o패턴과 일치하는 항목만 인쇄하는 옵션이 있습니다. 이는 Lookaround 어설션을 사용하여 결합될 수 있습니다(아래 설명 참조).Perlre 맨페이지의 확장 모드)은 대상과 일치한다고 판단된 것에서 grep 패턴의 일부를 제거합니다 -o.

$ grep -oP 'foobar \K\w+' test.txt
bash
happy
$

이는 출력하려는 ​​텍스트 앞에 너비가 0인 LookBehind 어설션으로 사용할 수 \K있는 짧은 형식(더 효율적)입니다 . 출력할 텍스트 뒤에 너비가 0인 예측 어설션으로 사용할 수 있습니다.(?<=pattern)(?=pattern)

foo예를 들어, 와 사이의 단어를 일치시키려면 bar다음을 사용할 수 있습니다.

$ grep -oP 'foo \K\w+(?= bar)' test.txt

또는 (대칭을 위해)

$ grep -oP '(?<=foo )\w+(?= bar)' test.txt

답변2

    sed -n "s/^.*foobar\s*\(\S*\).*$/\1/p"

-n     suppress printing
s      substitute
^.*    anything before foobar
foobar initial search match
\s*    any white space character (space)
\(     start capture group
\S*    capture any non-white space character (word)
\)     end capture group
.*$    anything after the capture group
\1     substitute everything with the 1st capture group
p      print it

답변3

표준 grep은 이것을 할 수 없지만최신 버전의 GNU grep은 다음을 수행할 수 있습니다.. sed, awk 또는 perl을 사용할 수 있습니다. 다음은 샘플 입력에서 원하는 작업을 수행하는 몇 가지 예입니다. 특수한 경우에는 약간 다르게 동작합니다.

foobar word other stuff로 교체 word하고 교체가 완료된 후에만 인쇄합니다.

sed -n -e 's/^foobar \([[:alnum:]]\+\).*/\1/p'

첫 번째 단어가 이면 foobar두 번째 단어를 인쇄합니다.

awk '$1 == "foobar" {print $2}'

foobar첫 번째 단어이면 삭제하고, 그렇지 않으면 줄을 건너뛴 다음 첫 번째 공백 뒤의 모든 항목을 삭제하고 인쇄합니다.

perl -lne 's/^foobar\s+// or next; s/\s.*//; print'

답변4

글쎄요, foobar가 항상 첫 번째 단어나 줄이라는 것을 알고 있다면 cut을 사용할 수 있습니다. 이와 같이:

grep "foobar" test.file | cut -d" " -f2

관련 정보