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
합니다. 입력에서 일치하지 않는 행을 무시 하도록 지시하는 방법 입니다. 그럼 어떻게할까요?
답변
일반 sed의 또 다른 방법 :
sed -e 's/.../.../;t;d'
s///
substituion이며, t
어떤 레이블이 조건에 모두 다음 명령을 생략하지 않고 d
행을 삭제합니다.
perl 또는 grep이 필요하지 않습니다.
(Nicholas Riley의 제안에 따라 편집 됨)
답변
일치하지 않는 줄을 인쇄하지 않으려면 다음 조합을 사용할 수 있습니다.
-n
sed에게 인쇄하지 않도록 지시하는 옵션p
sed에게 일치하는 것을 인쇄하도록 지시하는 플래그
이것은 다음을 제공합니다.
sed -n 's/.../.../p'
답변
Perl 사용 :
... |& perl -ne 'print "$1\n" if /^\[wrote (.*\.class)\]$/'
답변
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
답변
sed -n '/.../!p'
대체 할 필요가 없습니다.
답변
