sed : 일치하는 그룹 만 인쇄


133

마지막 두 숫자 (1 개의 정수, 1 개의 부동 소수점, 선택적 공백)를 잡고 인쇄 만하고 싶습니다.

예:

foo bar <foo> bla 1 2 3.4

인쇄해야합니다 :

2 3.4

지금까지 다음과 같은 내용이 있습니다.

sed -n  's/\([0-9][0-9]*[\ \t][0-9.]*[\ \t]*$\)/replacement/p' 

나에게 줄거야

foo bar <foo> bla 1 replacement

그러나 그룹 1로 바꾸려고하면 전체 줄이 인쇄됩니다.

sed -n  's/\([0-9][0-9]*[\ \t][0-9.]*[\ \t]*$\)/\1/p' 

그룹의 정규 표현식과 일치하는 줄 섹션 만 인쇄하려면 어떻게해야합니까?

답변:


138

전체 줄과 일치하므로 .*정규 표현식의 시작 부분에 a 를 추가 하십시오. 이로 인해 전체 줄이 그룹의 내용으로 바뀝니다.

echo "foo bar <foo> bla 1 2 3.4" |
 sed -n  's/.*\([0-9][0-9]*[\ \t][0-9.]*[ \t]*$\)/\1/p'
2 3.4

38
-r--regexp-extended 옵션 을 추가해야했다. 그렇지 않으면 invalid reference \1 on s '명령의 RHS` 오류가 발생했다.
Daniel Sokolowski

15
@DanielSokolowski 난 당신이 사용하는 경우 그 오류를 얻을 생각 ()대신 \(\).
Daniel Darabos 2016 년

3
또한 .*추출하려는 문자열이 항상 줄의 끝이 아닌 경우 정규 표현식의 끝에 추가 해야합니다.
Teemu Leisti

3
.*욕심이 많고 sed가 욕심 .*?
스럽지

것을 @DanielDarabos 그냥 언급 ()우분투 16.04에 오류가 발생하지 않습니다. 그래서 나는이 의견이 구식이라고 생각합니다.
Li haonan

72

grep 은 추출에 적합한 도구입니다.

귀하의 예와 정규식을 사용하여 :

kent$  echo 'foo bar <foo> bla 1 2 3.4'|grep -o '[0-9][0-9]*[\ \t][0-9.]*[\ \t]*$'
2 3.4


grep -o는 msysgit을 실행하는 시스템에서 이식되지 않지만 sed는 실행됩니다.
cchamberlain

grep 으로이 문제를 해결하기 위해 look-ahead와 look-behind를 사용하는 답변은 @jozxyqk에 의해 연결된 질문을 참조하십시오.
Joachim Breitner

파이프 된 grep -o통화 가있는 패턴에서 그룹을 추출 할 수 있습니다 . stackoverflow.com/a/58314379/117471
Bruno Bronosky '10

12

그리고 또 다른 옵션으로, 나는 awk와 함께 갈 것입니다!

echo "foo bar <foo> bla 1 2 3.4" | awk '{ print $(NF-1), $NF; }'

이것은 공백으로 입력을 나누고 (여기서는 STDIN을 사용하고 있지만 입력은 쉽게 파일 일 수 있음) 마지막-한 필드와 마지막 필드를 인쇄합니다. $NF변수 필드의 수는 공간의 폭발 후 발견 잡아.

이것의 장점은 마지막 두 필드 만 계속 바뀌면 마지막 두 필드가 바뀌는 것이 중요하지 않다는 것입니다.


3

절단 명령은이 정확한 상황을 위해 설계되었습니다. 구분 기호를 "잘라 내고"출력 할 청크를 지정할 수 있습니다.

예를 들어 : echo "foo bar <foo> bla 1 2 3.4" | cut -d " " -f 6-7

결과는 다음과 같습니다. 2 3.4

-d는 구분자를 설정합니다

-f는 출력 할 '필드'범위를 선택합니다.이 경우 원래 문자열의 6 ~ 7 번째 청크입니다. 범위를 목록으로 지정할 수도 있습니다 (예 :) 6,7.


특정 열만 인쇄하려면awk '{ print $2" "$6 }'
nurettin

@ nurettin 귀하의 의견이 awk 답변 중 하나를 의미한다고 생각합니다.
carlin.scott 2016 년

나는이 페이지를 방문했을 때 잘라 내고 한계를 깨달았고이 게시물의 품질을 향상시키기위한 주석 대신 awk 로보 다 일반적인 버전을 작성하기로 결정했습니다.
nurettin

1
네, awk와 관련된 다른 대답에 속한다고 생각합니다. 당신이 쓴 것을하는 컷 명령은 :cut -d " " -f 2,6
carlin.scott

아, 몰랐어요, 당신은 범위를 줄 수 있다고 생각했습니다. 고마워
nurettin

2

나는 동의 @kent 이 잘 적합된다 grep -o. 패턴 내에서 그룹을 추출해야하는 경우 두 번째 grep으로 그룹을 수행 할 수 있습니다.

# To extract \1 from /xx([0-9]+)yy/
$ echo "aa678bb xx123yy xx4yy aa42 aa9bb" | grep -Eo 'xx[0-9]+yy' | grep -Eo '[0-9]+'
123
4

# To extract \1 from /a([0-9]+)b/
$ echo "aa678bb xx123yy xx4yy aa42 aa9bb" | grep -Eo 'a[0-9]+b' | grep -Eo '[0-9]+'
678
9
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.