![패턴 1에서 두 번째로 나타나는 패턴 2까지의 텍스트를 제거하시겠습니까?](https://linux55.com/image/124303/%ED%8C%A8%ED%84%B4%201%EC%97%90%EC%84%9C%20%EB%91%90%20%EB%B2%88%EC%A7%B8%EB%A1%9C%20%EB%82%98%ED%83%80%EB%82%98%EB%8A%94%20%ED%8C%A8%ED%84%B4%202%EA%B9%8C%EC%A7%80%EC%9D%98%20%ED%85%8D%EC%8A%A4%ED%8A%B8%EB%A5%BC%20%EC%A0%9C%EA%B1%B0%ED%95%98%EC%8B%9C%EA%B2%A0%EC%8A%B5%EB%8B%88%EA%B9%8C%3F.png)
다음과 같은 텍스트 파일이 있습니다.
<!--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
설명하다
grep -Pz
-P
- 패턴을 Perl 호환 정규식(PCRE)으로 해석합니다.-z
-input.txt
하나의 큰 선으로 취급하세요.
(?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