패턴 1에서 두 번째로 나타나는 패턴 2까지의 텍스트를 제거하시겠습니까?

패턴 1에서 두 번째로 나타나는 패턴 2까지의 텍스트를 제거하시겠습니까?

다음과 같은 텍스트 파일이 있습니다.

<!--START OF FILE -->
random text
<meta> more random text </meta>
x x x x x x x 
more random text
that I dont need 
x x x x x x x

I need everything
from this point
onwards
...

다음과 같이 <!--START OF FILE -->두 번째와 두 번째 사이의 모든 항목을 삭제해야 합니다 .x x x x x x x

I need everything
from this point
onwards
...

을 사용해 보았지만 이는 내가 원하는 것이 아닌 sed '/<!--START OF FILE -->/,/x x x x x x x/d' test.txt첫 번째 발생 사이의 장벽을 제거합니다 .x x x x x x x

답변1

이건 정반대야

패턴 1과 패턴 2의 두 번째 일치 사이의 선을 어떻게 인쇄합니까?

당신 과 sed비슷한 일을 해보세요 :

sed -n '/PATTERN1/,$!{         # if not in this range
p;d                            # print and delete
}
/PATTERN2/!d                   # delete if it doesn't match PATTERN2
x;//!d                         # exchange and then, again, delete if no match
: do                           # label "do" (executed only after the 2nd match)
n;p                            # get the next line and print
b do' infile                   # go to label "do"

또는 한 줄에( gnu설정에서):

sed -n '/PATTERN1/,$!{p;d;};/PATTERN2/!d;x;//!d;: do;n;p;b do' infile

물론, 사용하고 카운터하는 것이 더 쉽습니다 awk. 연습용으로 남겨두겠습니다...

답변2

이해하기 쉬운 awk:

$ awk '/<!--START OF FILE -->/ {a=2}; !a; /x x x x x x x/ && a {a--}' < data

I need everything
from this point
...

0으로 인쇄 a하고 볼 때 감소합니다 x x x ....

또는 패턴 대신 파일의 실제 시작 부분부터 시작하여 첫 번째 블록을 BEGIN {a=2}.

예제 입력에는 두 번째 줄 다음에 빈 줄이 있습니다 x x x.... 해당 줄에서 행 삭제를 중지해도 출력에는 여전히 남아 있습니다 x x x....

답변3

grep -Pz '(?s)<!--START OF FILE(.*?x x x x x x x){2}\K.*' input.txt

설명하다

  1. grep -Pz

    • -P- 패턴을 Perl 호환 정규식(PCRE)으로 해석합니다.
    • -z- input.txt하나의 큰 선으로 취급하세요.
  2. (?s)<!--START OF FILE(.*?x x x x x x x){2}\K.*

    • (?s)- 나머지 정규식에 대해 "Dot Match Newline"을 활성화합니다.
    • .*?- 욕심없는 매칭.
    • {2}- 패턴의 반복 횟수입니다.
    • \K- 최종 일치 문자열에서 이전에 일치한 문자를 모두 생략합니다.

답변4

이 스니펫:

# Utility functions: print-as-echo, print-line-with-visual-space.
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
pl " Input data file $FILE:"
head -v -n 20 $FILE

pl " Expected output on file $E:"
head -v $E

pl " Results:"
cgrep -V -D -w '<!--START OF FILE -->' +2 +w 'x x x x x x x' 'meta' $FILE

생산하다:

-----
 Input data file data1:
==> data1 <==
<!--START OF FILE -->
random text
<meta> more random text </meta>
x x x x x x x 
more random text
that I dont need 
x x x x x x x

I need everything
from this point

-----
 Expected output on file expected-output1:

I need everything
from this point
onwards
...

-----
 Results:

I need everything
from this point
onwards
...

이는 "...START..."(-w)로 시작하고 문자열 "...x x..."(+w)의 두 번째 발생(+2)으로 끝나는 문자열을 생략(-V)합니다. ) 창문. ' 창에 'meta'라는 문자열이 있습니다.

이러한 시스템에서는:

OS, ker|rel, machine: Linux, 3.16.0-4-amd64, x86_64
Distribution        : Debian 8.9 (jessie) 
bash GNU bash 4.3.30

cgrep에 대한 자세한 내용은 다음과 같습니다.

cgrep   shows context of matching patterns found in files (man)
Path    : ~/executable/cgrep
Version : 8.15
Type    : ELF 64-bit LSB executable, x86-64, version 1 (SYS ...)
Home    : http://sourceforge.net/projects/cgrep/ (doc)

cgrep을 구하고 컴파일해야 하지만 32비트 또는 64비트 시스템에서 수행하는 데 아무런 문제가 없었으며 Brew를 통해 macOS(High Sierra)에서 작동합니다. 실행 시간은 GNU grep과 비슷합니다.

행운을 빕니다... 건배, drl

관련 정보