sed가 일치하지 않는 줄을 무시하도록했습니다.


93

sed일부 표현식에 따라 필터 매칭 라인을 만들 수 있지만 일치하지 않는 라인은 인쇄하지 않고 무시할 수 있습니까?

실제 예로, scalac파일 세트에서 (Scala 컴파일러) 를 실행 하고 -verbose생성 된 .class파일을 출력에서 읽고 싶습니다 . scalac -verbose많은 메시지를 출력하지만 우리는 형식의 메시지에만 관심이 [wrote some-class-name.class]있습니다. 내가 현재하고있는 것은 이것이다 ( |&bash 4.0의 stderr를 다음 프로그램으로 파이프하는 방법입니다).

$ scalac -verbose some-file.scala ... |& sed 's/^\[wrote \(.*\.class\)\]$/\1/'

이렇게하면 우리가 관심있는 메시지에서 파일 이름이 추출되지만 다른 모든 메시지도 변경되지 않은 상태로 전달됩니다! 물론 다음과 같이 할 수 있습니다.

$ scalac -verbose some-file.scala ... |& grep '^\[wrote .*\.class\]$' |
  sed 's/^\[wrote \(.*\.class\)\]$/\1/'

작동하지만 실제 문제를 해결하는 것과 매우 유사 sed합니다. 입력에서 일치하지 않는 행을 무시 하도록 지시하는 방법 입니다. 그럼 어떻게할까요?


2
허용되는 답변은 mouviciel의 답변이어야합니다. stackoverflow.com/a/1665574/869951
Oliver

답변:


90

일반 sed의 또 다른 방법 :

sed -e 's/.../.../;t;d'

s///substituion이며, t어떤 레이블이 조건에 모두 다음 명령을 생략하지 않고 d행을 삭제합니다.

perl 또는 grep이 필요하지 않습니다.

(Nicholas Riley의 제안에 따라 편집 됨)


3
OS X에서 10.8.2 나는 분리했다 txd줄 바꿈이 아니라 내가 얻고 있었다으로 세미콜론 undefined label 'x;d;:x'.
davidchambers

6
더 좋은 점 : sed -e 's/.../.../' -e 'tx' -e 'd' -e ':x'( 비슷한 질문 에 대한 의견에서 제 안됨).
davidchambers

1
레이블이 제공되지 않으면 't'가 스크립트의 끝으로 전송되므로 더 간단 sed -e 's/.../.../' -e 't' -e 'd'합니다..
Nicholas Riley

사람들은 -e옵션 의 의미를 모르기 때문에 일반적으로 언급하지 마십시오.
Fredrick Gauss

246

일치하지 않는 줄을 인쇄하지 않으려면 다음 조합을 사용할 수 있습니다.

  • -n sed에게 인쇄하지 않도록 지시하는 옵션
  • p sed에게 일치하는 것을 인쇄하도록 지시하는 플래그

이것은 다음을 제공합니다.

sed -n 's/.../.../p'

3
이 방법의 한 가지 단점은 일치하는 표현식이 여러 개인 경우 결과도 여러 번 인쇄된다는 것입니다. 예를 들어 : echo foo | sed -n -e 's/foo/bar/p' -e 's/bar/oof/p'baroof별도의 행에 모두 출력합니다 . goto-label 다양성은 첫 번째 패턴이 일치하지 않으면 줄을 삭제하므로 여러 패턴을 처리 할 수 ​​없습니다.
Rapsey

@Rapsey는 두 번 인쇄하라고 말하고 있기 때문입니다. 단일 sed 명령에서 두 번 인쇄하도록 지시했으며 각 인스턴스는 제자리에서 인쇄됩니다 (또는 버퍼링 될 수 있음). -e 대신 파이프를 사용하거나 마지막 -e에 'p'만 넣어야합니다.
미생물

@Rapsey :이 관련 포인트에 대한 내 답변을 참조하십시오
Amessihel

@microbial, 마지막 p 플래그가 마지막 대체 표현식에 의해 일치하는 각 줄에서 작동하므로 작동하지 않습니다 .
Amessihel


0

Rapsey는 다중 대체 표현식에 대해 관련있는 지적을했습니다.

  • 먼저 Unix SE 답변을 인용하면 "대부분의 sed 명령에 적용되는 행을 제한하는 주소를 접두사로 붙일"수 있습니다.
  • 둘째, 중괄호 {}(세미콜론으로 구분)로 명령을 그룹화 할 수 있습니다.; 또는 새 줄로
  • 셋째, 마지막 대체에 인쇄 플래그 p 를 추가합니다.

통사론:

sed -n -e '/^given_regexp/ {s/regexp1/replacement1/flags1;[...];s/regexp1/replacement1/flagsnp}'

예 ( 자세한 내용 은 여기 문서 참조) :

  • 암호:

    sed -n -e '/^ha/ {s/h/k/gp;s/a/e/g}' <<SAMPLE
    haha
    hihi
    SAMPLE
    
  • 결과:

    kaka
    

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