쉘 스크립트: 특정 라인에서 패턴과 일치하는 두 개의 연속 라인을 삭제하고 싶습니다.

쉘 스크립트: 특정 라인에서 패턴과 일치하는 두 개의 연속 라인을 삭제하고 싶습니다.

파일의 특정 줄의 패턴과 일치하는 특정 두 개의 연속 줄을 삭제하고 싶습니다.

예를 들어 파일 내용은 아래와 같습니다.

Line1: a
Line2: b
Line3: c
Line4: Name: 123
Line5:  xyz
Line6: Name: 456
Line7:  abc

"Name:"으로 시작하는 첫 번째 줄 패턴과 공백으로 시작하는 두 번째 줄 패턴과 일치하는 4번째 줄부터 시작하여 두 개의 연속된 줄을 삭제하고 싶습니다.

sed쉘 이나 다른 것을 사용하여 이를 수행하는 효율적인 방법이 있습니까 ?

좀 더 명확히 하기 위해 MANIFEST.MF에서 서명/체크섬 정보를 제거하고 싶습니다.

아래와 같은 샘플 MANIFEST.MF: 아래 매니페스트 파일에서 "Name: " 항목을 제거하고 싶습니다. 여기서 "이름:" 항목은 한 줄 또는 두 줄 이상일 수 있습니다.

처음에 내 솔루션은 첫 번째 "이름:" 항목을 찾은 다음 "SHA-256-Digest:" 항목을 찾아 파일 끝까지 삭제하는 것과 같았습니다. 불행하게도 이 솔루션은 중간에 필요한 항목 하나를 제거하는 문제가 있습니다. 예를 들어 "NetBeans-Simply-Convertible: "도 제거됩니다.

이제 한 줄에 사용 가능한 경우 "이름:" 항목을 제거하거나 2줄 이상에 걸쳐 있는 항목을 제거하고 싶습니다. 하지만 "Name: " 항목을 제거하는 동안 "NetBeans-Simply-Convertible: "과 같은 항목을 잃어서는 안 됩니다.

이미 파일에서 아래 명령을 사용하여 "SHA-256-Digest: " 항목을 제거하고 있습니다.sed -i "/^\SHA-256-Digest: /d" $manifest_file


Manifest-Version: 1.0
Version-Info: ....

Name: com/abc/xyz/pqr/client/relationship/message/notifier/Relati
 onshipUpdateNotifierFactory.class
SHA-256-Digest: cSSyk6Y2L2F9N6FPtswUkxjF2kelMkGe4bFprcQ+3uY=

Name: com/abc/xyz/pqr/client/relationship/ui/BaseRelationshipView
 $5.class
SHA-256-Digest: w9HgRjDuP024U4CyxeKPYFe6rzuzxZF3b+9LVG36XP8=

Name: com/abc/xyz/pqr/client/impl/MofRelationshipAgentImpl.class
SHA-256-Digest: GwIBIU+UdPtjyRhayAVM90Eo+SwCT/kP65dI59adEnM=

Name: com/abc/xyz/pqr/client/settings/ConvertibleProperties.class
NetBeans-Simply-Convertible: {com/abc/xyz/pqr/client/settings}Con
 vertibleProperties
SHA-256-Digest: 5FszAtfpPXcLx/6FBWbfeg6E4fwFMRozV+Q+3rReATc= ...

예상 출력:

Manifest-Version: 1.0
Version-Info: ....


NetBeans-Simply-Convertible: {com/abc/xyz/pqr/client/settings}Con
 vertibleProperties

...

답변1

접근하다:

다음과 같은 입력 파일이 있다고 가정해 보겠습니다 file.txt(각 줄에 Line<number>:첫 번째 필드가 포함되어 있음을 고려).

Line1: a
Line2: b
Line3: c
Line4: Name: 123
Line5:  xyz
Line6: Name: 456
Line7:  abc
Line8: Name: 111
Line9: www
Line10: Num: 222
Line11:  abc
Line12: Name: 333
Line13:  ccc

awk '{ if ($2 == "Name:") { 
           if ((getline l) > 0){ 
               if (l ~ /^\S+  \S+/) { next } else { print $0 RS l }               
           }
       } else { print } 
}' file.txt

출력:

Line1: a
Line2: b
Line3: c
Line8: Name: 111
Line9: www
Line10: Num: 222
Line11:  abc

'getline var'- awk의 입력에서 변수로 다음 레코드를 읽습니다.var

그만큼getline명령은 레코드를 찾으면 1을 반환하고 파일의 끝을 발견하면 0을 반환합니다.

답변2

당신이 요구하는 것이 명확하지 않다는 것을 알 수 있습니다. 하나의 답변은 4줄(일치하는 두 줄과 후속 두 줄)을 삭제합니다. 다른 사람은 모든 것을 삭제합니다하지만어울리는 라인..

나는 당신이 원하는 것을 던질 것입니다. 일치하는 줄 Name: 123과 그 다음 줄의 두 줄을 삭제합니다. 나는 이것을 다음과 같이 한다 sed:

sed -e '/Name: 123/{N;d}' filename

답변3

사용 ed:

$ printf '%s\n' 'g/^ / s///\' '-,.j' 'g/^Name: /d' 'g/SHA-256-Digest: /d' '4,$g/^$/d' ,p Q | ed -s file
Manifest-Version: 1.0
Version-Info: ....

NetBeans-Simply-Convertible: {com/abc/xyz/pqr/client/settings}ConvertibleProperties

그러면 입력 파일에 다음 편집 스크립트가 적용됩니다.

g/^ / s///\
-,.j
g/^Name: /d
g/SHA-256-Digest: /d
4,$g/^$/d
,p
Q

이는 6개의 개별 명령으로 구성됩니다.

  1. 두 명령은 공백 문자로 시작하는 모든 줄에 적용됩니다 s///. 명령 -,. j의 빈 정규 표현식은 이전 명령의 표현식(정규 표현식과 일치하는 행에 하나 이상의 명령을 적용하는 데 사용됨) s을 재사용하므로 명령은 빈 공백으로 시작하는 행에서 첫 번째 빈 공간을 제거합니다. 그런 다음 이 명령은 수정된 줄을 이전 줄과 결합합니다. 이렇게 하면 입력 데이터의 줄 바꿈이 효과적으로 취소됩니다.^gsj

  2. 이 명령은 d로 시작하는 모든 줄에 적용되어 Name:이를 제거합니다.

  3. 마찬가지로,로 시작하는 줄이 SHA-256-Digest:제거됩니다.

  4. 4번째 줄부터는 빈 줄이 제거됩니다.

  5. 결과를 표시하기 위해 전체 버퍼를 표준 출력으로 출력합니다.

  6. Q무조건 편집기를 종료합니다( wq변경 사항을 원래 파일에 다시 쓰는 데 사용할 수 있음).

답변4

sed -e '
   4,$!d;      # skip non-relevant portion
   /Name:/N;   # grab the line coming after Name:
   /\n.* /d;   # what we were after is not this
   P;D
' yourfile

관련 정보