기본적으로 두 문자열 사이의 내용을 가져오려고 하는데 다음과 같이 동일한 문자를 N 번 반복합니다.
===
This is a test
===
====
Another test
====
==
Last test
==
물론 위의 내용은 단지 예시일 뿐이다. 내 시도와 결과는 다음과 같습니다.
sed -u '/==/!d;s//&\n/;s/.*\n//;:a;/==/bb;$!{n;ba};:b;s//\n&/;P;D' testfile
주다
=
This is a test
=
Another test
Last test
위 중 하나를 사용하는 경우 testfile
:
Last test
이렇게 하면 원하는 결과를 얻을 수 있습니다(비록 줄바꿈이 너무 많이 추가되기는 하지만 이 예에서는 괜찮습니다).
위의 방법은 이러한 반복 문자의 인스턴스가 하나만 있거나 내용이 포함된 고유 문자열 쌍인 경우에만 작동합니다.
반복되는 문자 수가 동일한 두 문자열 사이의 내용을 얻는 방법은 무엇입니까? 나는 이것을 사용하거나 grep
이를 달성하는 것을 sed
선호 합니다.awk
답변1
우리는 사용앗다음과 같은 트리거 로직을 사용하여 열린 상태에서 닫힌 상태로 전환하는 유틸리티입니다.
$ awk -v str="==" '
$0""==str{f=!f;next};f
' testfile
Last test
Posixly 사용sed트리거 로직의 구성을 구현할 수 있습니다.
sed -ne '
/^==$/{
x; # access state info from hold
s/^$/0/; # initialize state
y/01/10/; # toggle state
x; # save state in hold
d; # next
}
G;/\n1/P
' testfile
스트림 편집기의 GNU 버전 사용sed확장 모드에서-E
$ sed -Ee '
$!N; /^(\S)\1+\n/!D
:loop
$d;N
s/^(.*)\n(.*)\n\1$/\2/;t
bloop
' testfile
This is a test
Another test
Last test
노트:-
- 명령을 통해
N
두 줄 패턴 공간을 유지합니다 . - 황금색 라인에 도달할 때까지 라인을 계속 거부합니다(=> 패턴 공간의 첫 번째 부분에 공백이 아닌 문자의 단일 유형만 포함되어 있음).
- 그러한 선을 찾으면 도로에서 선과 정확히 일치하는 복제본이 두 개 이상 나타날 때까지 반복합니다. 우리는 첫 번째 그룹을 찾았습니다.
- eof에 도달할 때까지 이 과정을 반복합니다.
...
트리거 연산자 사용진주다음과 같이 이를 수행할 수 있습니다.
perl -lne 'print if
/^(\S)\1+$(?{$a=$_})/ ... $_ eq $a and $_ ne $a;
' testfile
고정된 미리 결정된 문자열을 검색하는 것이 훨씬 더 간단합니다. 그 이후에는 정규식을 작성할 필요가 없고 문자열 동등성 테스트만으로 충분합니다.
$ perl -nlse 'print if
$_ eq $a ... $_ eq $a and $_ ne $a;
' -- -a=== testfile
$ sed -Ee '
/^==$/!d
$!N
:a
$d;N
s/^(.*)\n(.*)\n\1$/\2/;t
ba
' testfile
답변2
너무 길어요.
$ sed '/^==*$/,//{//!p};d' testfile
This is a test
Another test
Last test
언뜻 보기에 간단한 범위는 모든 쌍을 인쇄합니다(루핑이 필요하지 않음).
$ sed -n '/^=/,//p' testfile
===
This is a test
===
====
Another test
====
==
Last test
==
=
( )로 시작하는 줄 과 다음 반복되는 정규식( ) //
사이의 모든 줄을 인쇄합니다 .
라인으로 개선할 수 있습니다.오직포함하다 =
: /^==*$/
.
모든 마커를 제거합니다.
$ sed -n '/^==*$/,//H;${x;s/\n==*//g;s/^\n//;p}' testfile
This is a test
Another test
Last test
또는 더 짧은 형식으로:
$ sed -n '/^==*$/,//{//d;p}' testfile
This is a test
Another test
Last test
정확한 수량을 일치시키려면 =
정규 표현식을 다음과 같이 변경하세요.
$ sed -n '/^==$/,//{//d;p}' testfile
Last test
그리고 해당 -n
옵션을 피하려면 다음을 수행하십시오.
$ sed '/^==$/,//{//!p};d' testfile
Last test
awk에서는 다음과 같이 할 수 있습니다.
$ awk 'p==0 && /^==*$/ {p=1;next}
p==1 && /^==*$/ {p=0}
p
' testfile
This is a test
Another test
Last test
또는 덜 명시적인 형태로:
awk ' /^==*$/ { p = !p ; next}
p
' testfile
답변3
나는 다음을 사용할 것이다 perl
:
$ perl -0777 -ne 'print $3 while /^((\S)\2+\n)(.*?)^\1/smg' < your-file
This is a test
Another test
Last test
또는 pcregrep
:
$ pcregrep -Mo3 '(?s)^((\S)\2+\n)(.*?)\n?^\1' < your-file
This is a test
Another test
Last test
고정 구분 기호 사이의 콘텐츠를 반환하는 경우:
$ pcregrep -Mo1 '(?s)^==\n(.*?)\n?^==$' < your-file
Last test
답변4
주문하다:
awk '{a[++i]=$0}/==/{for(x=NR-1;x<NR;x++)print a[x]}' filename|sed '/^$/d'
산출
This is a test
Another test
Last test