내 파일에 시작 키워드 "Start", 끝 키워드 "End" 및 그 사이의 선택적 텍스트가 포함된 알 수 없는 수의 텍스트 블록이 포함되어 있으며 각 줄에 정확한 키워드 "Disk"가 있습니다. "에 있는 텍스트 블록을 삭제해야 합니다. 그들 사이에는 어떤 관계도 없습니다. 예를 참조하세요.
다음과 같이 입력을 처리하고 있습니다.
Server1:Start
Server1:End
Server2:Start
Disk1
Disk2
Server2:End
Server3:Start
Disk1
Server3:End
, 내가 원하는 출력은 다음과 같습니다.
Server2:Start
Disk1
Disk2
Server2:End
Server3:Start
Disk1
Server3:End
"awk" 또는 "sed"를 사용하여 두 줄 사이의 텍스트를 찾을 수 있다는 것을 알고 있지만, 두 줄이 여러 번 나타나거나 두 줄 사이에 텍스트가 없으면 어떻게 해야 할지 모르겠습니다.
우분투 17.10을 실행 중입니다.
어떤 도움이라도 기다리겠습니다.
편집: 를 사용하여 이 작업을 수행할 수 있다고 생각했기 때문에 처음으로 게시물을 삭제했지만 sed -e '/Start/,/End/d'
이로 인해 실제로 모든 것이 삭제되었습니다.
답변1
Start
연속된 행 과 행을 삭제하려면 End
GNU sed에서 다음을 수행해야 합니다:
$ sed -e '/Start/ {N; /^\(.*\):Start\n\1:End$/d }' < input
가 보이면 Start
다음 줄을 로드 N
하고 버퍼의 내용이 두 줄 모두 동일한지 확인하세요( Somename:Start\nSomename:End
개행 문자). 있는 경우 삭제하십시오. 여기서는 쌍의 첫 번째 그룹에 대한 참조이며 거기에서 발견된 동일한 문자열과 일치합니다. 임의의 문자( ) 중 임의의 숫자( )만 나타냅니다.Somename
\n
\1
\(..\)
.*
*
.
sed -e '/Start/,/End/d'
범위가 시작 패턴과 끝 패턴 사이의 모든 라인과 일치하기 때문에 를 사용하면 모든 라인이 삭제됩니다. 입력의 모든 내용은 사이에 있으므로 Start
모든 End
내용이 삭제됩니다.
답변2
나는 이러한 작업을 awk에서 수행하는 것을 좋아하기 때문에 또 다른 솔루션입니다.
BEGIN {
RS="End\n"
ORS="End\n"
}
NF > 2
내장 RS
또는 레코드 분리 변수를 사용하여 awk는 그 사이의 각 항목을 End\n
레코드로 처리하고 및 둘 다 단일 단어 servername:Start
라고 가정합니다 servername:End
. 이는 line을 통해 두 개 이상의 필드가 있는 행을 인쇄하는 경우에만 해당됩니다 NF > 2
. 이것이 true이면 전체 행이 인쇄되어 End\n
출력 레코드 구분 기호로 사용됩니다( ORS
).
~$>echo '
Server1:Start
Server1:End
Server2:Start
Disk1
Disk2
Server2:End
Server3:Start
Disk1
Server3:End
' | awk 'BEGIN { RS="End\n"; ORS="End\n"; } NF > 2;'
Server2:Start
Disk1
Disk2
Server2:End
Server3:Start
Disk1
Server3:End