특정 문자열이 포함 된 줄과 다음 줄을 제거합니다.

사용합니다

cat foo.txt | sed "/bar/d"

파일에서 bar 문자열이 포함 된 줄을 제거합니다.

그러나 해당 줄과 줄을 직접 제거하고 싶습니다. 그 후에 . 바람직하게는 sed, awk 또는 MinGW32에서 사용할 수있는 기타 도구에서 사용할 수 있습니다.

이것은 일종의 반대입니다. 일치하는 줄을 인쇄하기 위해 -A-B를 사용하여 grep에서 얻을 수있는 것 중 일치하는 줄 앞 / 뒤의 줄로.

쉽게 달성 할 수있는 방법이 있나요?

댓글

  • 정보 : ' 항목이 2 줄인 로그를 분석하고 있습니다. 따라서 패턴과 일치하는 항목을 찾아서 다음 줄뿐만 아니라 제거하고 싶습니다. 따라서 ' 연속 매치 라인을 처리 할 필요는 없지만 답변을 완전하게 해주셔서 감사합니다!

Answer

GNU sed (비 임베디드 Linux 또는 Cygwin) :

sed "/bar/,+1 d" 

연속 된 두 줄에 bar가있는 경우 분석하지 않고 두 번째 줄을 삭제합니다. 예를 들어 3 줄 파일 bar / bar / foo가있는 경우 foo 줄은 그대로 유지됩니다.

댓글

  • 길이에 +1 🙂 특히 예를 들어 ' 연속 된 bar가 없으므로 기억하기가 매우 쉽습니다.
  • sed '/bar/d' " 특정 문자열을 포함하는 행을 " 제거하고 제거하려는 경우

b> 다음.

  • 수학 후에 모든 줄을 제거하려면?
  • @Pandya That '은 다릅니다. 예를 들어 사용할 수 있습니다. sed '/math/q'
  • @ A.K. 일치하는 줄만 삭제하려는 경우 ' 더 간단합니다. sed '/bar/d'
  • 답변

    bar가 연속 된 줄에 나타날 수있는 경우 다음을 수행 할 수 있습니다.

    awk "/bar/{n=2}; n {n--; next}; 1" < infile > outfile 

    위의 2 줄을 일치하는 줄을 포함하여 삭제할 줄 수로 변경하여 두 줄 이상을 삭제하도록 조정할 수 있습니다.

    그렇지 않은 경우 “ @MichaelRollins”솔루션 을 사용하여 sed에서 쉽게 수행하거나 :

    sed "/bar/,/^/d" < infile > outfile 

    댓글

    • AWK 솔루션의 또 다른 장점은 /bar/를 다음으로 대체 할 수 있다는 것입니다. /bar|baz|whatever/. sed에서 해당 구문이 ' 작동하지 않는 것 같습니다.
    • @ jakub.g, GNU sed ( v4.4 현재). 다른 사람들에 대해서는 확실하지 않습니다. 내가 아는 것은 기본적으로 " 기본 " 정규식 구문을 사용한다는 것입니다. 이것이 귀하의 예제가 작동하지 않습니다. 원하는 것을 얻으려면 각 수직선 앞에 백 슬래시를 넣거나 sed에 " 확장

    정규식. 자세한 정보 : gnu.org/software/sed/manual/html_node/ … 이는 grep에도 적용됩니다. ' 저만의 작업 예 : echo $'0a\n1b\n2c' | sed '/0a\|1b/d'.

    답변

    저는 sed에 능통하지 않지만 awk에서는 쉽게 할 수 있습니다.

    awk "/bar/{getline;next} 1" foo.txt 

    awk 스크립트는 다음과 같이 읽습니다. bar가 포함 된 행의 경우 다음 행 (getline)을 가져온 다음 모든 후속 처리 (다음)를 건너 뜁니다. 끝에있는 1 패턴은 나머지 줄을 인쇄합니다.

    업데이트

    코멘트에서 지적했듯이 위의 솔루션은 연속적인 bar. 다음은이를 고려한 수정 된 솔루션입니다.

    awk "/bar/ {while (/bar/ && getline>0) ; next} 1" foo.txt 

    이제 모든 / bar / 줄을 건너 뛰기 위해 계속 읽고 있습니다.

    주석

    • grep -A 100 %를 복제하려면 연속 된 줄을 올바르게 지정합니다 (전체 블록과 그 뒤에 한 줄을 제거하여).

    답변

    이를 위해 sed의 스크립팅 기능을 사용하는 것이 좋습니다.

    $ sed -e "/bar/ { $!N d }" sample1.txt 

    샘플 데이터 :

    $ cat sample1.txt foo bar biz baz buz 

    “N”명령은 패턴 공간에 입력의 다음 줄을 추가합니다. 이것은 패턴 일치 (/ bar /)의 줄과 결합되어 삭제하려는 줄이됩니다. 그런 다음 “d”명령으로 정상적으로 삭제하십시오.

    댓글

    • 콘솔에 줄 바꿈을 입력하려면 어떻게해야합니까? 아니면 스크립트 전용입니까?
    • @ jakub.g : GNU sed 사용 : sed -e '/bar/{N;d}' sample1.txt

    답변

    일치 바로 다음 줄을 제거해야하는 경우 sed 프로그램은 연속 일치를 고려해야합니다. 즉, 일치하는 줄을 제거하면 일치하는 줄도 제거해야합니다.

    충분히 구현되어 있지만 조금 뒤를 살펴 봐야합니다. .

    printf %s\\n 0 match 2 match match \ 5 6 match match match \ 10 11 12 match 14 15 | sed -ne"x;/match/!{g;//!p;}" 

     0 6 11 12 15  

    읽은 각 행에 대해 보류 및 패턴 공간을 바꾸는 방식으로 작동하므로 매번 마지막 행을 현재 행과 비교할 수 있습니다. 따라서 sed가 행을 읽을 때 버퍼의 내용을 교환하고 이전 행은 편집 버퍼의 내용이되고 현재 행은 보류 공간에 놓입니다.

    따라서 sed는 이전 줄에서 match 와 일치하는지 확인합니다. !를 찾을 수 없습니다. { 함수 }의 두 표현식이 실행됩니다. sedg 패턴 공간을 덮어 써 보류 공간을 설정합니다. 즉, 현재 행이 보류 및 패턴 공간에 있음을 의미합니다. 그런 다음 // 가장 최근에 컴파일 된 정규식 ( match )과 일치하는지 확인합니다. 그것 match 하지 않으면 p 린팅됩니다.

    즉, 행이 match 바로 이전 행이 하지 않는 경우에만 인쇄됨을 의미합니다. match . 또한 match 의 시퀀스에 대한 불필요한 교체를 방지합니다.

    임의의 줄 수를 삭제할 수있는 버전을 원하는 경우 match 이후에 발생하면 약간의 작업이 필요합니다.

    printf %s\\n 1 2 3 4 match \ match match 8 \ 9 10 11 12 13 \ 14 match match \ 17 18 19 20 21 | sed -net -e"/match/{h;n;//h;//!H;G;s/\n/&/5;D;}" -ep 

    . .. 제거 할 줄 수 (일치하는 줄 포함) 로 5를 바꿉니다 …


    1 2 3 4 12 13 14 21 

    답글 남기기

    이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다