GNU Grep이 선택된 그룹을 출력 할 수 있습니까?


47

GNU grep을 사용하여 표현식에서 일치하는 그룹을 얻을 수 있습니까?

예:

echo "foo 'bar'" | grep -oE "'([^']+)'"

" 'bar'"를 출력 할 것입니다. 그러나 나는 한 번 더 grep을 보내지 않고 "바"를 얻고 싶습니다 (즉, 일치하는 그룹을 얻습니다). 가능합니까?

답변:


50

sed이것을 위해 사용할 수 있습니다 . BSD에서 sed:

echo "foo 'bar'" | sed -E "s/.*'([^']+)'.*/\\1/"

또는 -E옵션이 없는 경우 :

sed "s/.*'\([^']\+\)'.*/\1/"

여러 줄 입력에는 작동하지 않습니다. 이를 위해서는 다음이 필요합니다.

sed -n "s/.*'\([^']\+\)'.*/\1/p"

고마워, sed에 대해 잊어 버렸다. 그러나 명확히하기 위해, sed는 논쟁을 -E.로 받아들이지 않습니다.
Torandi

흠, 그것은 내 컴퓨터 (Mac OS X)에서 작동합니다. 추가 검토 후 맨 페이지의 "-E, -a 및 -i 옵션은 비표준 FreeBSD 확장이며 다른 운영 체제에서는 사용하지 못할 수 있습니다."
jtbandes

1
-r 저에게 그런 것 같습니다.
Torandi

1
@jtbandes :이 표현에 확장 기능이 필요하지 않습니다. 3 개의 이스케이프 문자 만 ( ) +사용 \( \) \+하면됩니다.sed "s/.*'\([^']\+\)'.*/\1/"
실제로

2
여러 줄 입력에는 작동하지 않습니다. 이를 위해 다음이 필요합니다. sed -n "s/.*'\([^']\+\)'.*/\1/p"
phreakhead

28

grep이 특정 그룹을 출력 할 수는 없지만 lookahead 및 뒤에 어설 션을 사용하여 이후를 수행 할 수 있습니다.

echo "foo 'bar'" | grep -Po "(?<=')[^']+(?=')"


8
grep -P모든 플랫폼에서 사용 가능한 것은 아닙니다. 그러나 그렇다면 lookahead / behind를 사용하는 것이 문제를 해결하는 아주 좋은 방법입니다.
Sébastien 2016 년

1
grep이 룩 어스 어설 션으로 지능적입니까? 긴 비하인드에서 어떻게 수행됩니까? 룩-비하인드를 나머지 정규식과 함께 일종의 "접미사 트리"에 통합하고 있습니까?
Ross Rogers

3

\K일치 텍스트에 추가되지 않은 lookahead와 함께 왼쪽 일치 텍스트를 재설정하고 버릴 수 있습니다 .

$ echo "foo 'bar'" | grep -oP "'\K[^']+(?=')"
bar

GNU grep 만 해당합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.