파일이 있다고 가정해 보겠습니다.
# 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에는 -P
Perl 스타일 정규식 옵션과 -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