파일의 특정 줄의 패턴과 일치하는 특정 두 개의 연속 줄을 삭제하고 싶습니다.
예를 들어 파일 내용은 다음과 같습니다.
Line1: a
Line2: b
Line3: c
Line4: Name: 123
Line5: xyz
Line6: Name: 456
Line7: abc
4번째 줄에서 시작하는 줄을 찾고, "이름:"으로 시작하는 첫 번째 줄의 패턴과 일치하고, 공백으로 시작하는 두 번째 줄의 패턴과 일치하고, 두 개의 연속된 줄을 삭제하고 싶습니다.
sed
쉘이나 다른 방법을 사용하여 이를 수행하는 효율적인 방법이 있습니까 ?
좀 더 명확히 하기 위해 MANIFEST.MF에서 서명/체크섬 정보를 제거하고 싶습니다.
샘플 MANIFEST.MF는 다음과 같습니다. 아래 매니페스트 파일에서 "이름:" 항목을 제거하고 싶습니다. 여기서 "name:" 항목은 하나 또는 두 개(또는 그 이상) 줄에 있을 수 있습니다.
처음에 내 솔루션은 첫 번째 "이름:" 항목을 찾은 다음 "SHA-256-Digest:" 항목을 찾아 파일 끝까지 제거하는 것과 같았습니다. 불행하게도 이 솔루션은 중간에 필수 항목을 제거하는 문제가 있습니다. 예를 들어 "NetBeans-Simply-Convertible:"도 제거됩니다.
이제 1개 행에 사용 가능한 "이름:" 항목이나 2개 이상의 행에 걸쳐 있는 항목을 제거하고 싶습니다. 그러나 "이름:" 항목을 삭제할 때 "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
'라인 변수 가져오기'- awk 입력에서 다음 레코드를 변수로 읽습니다.var
이것줄을 서다명령이 레코드를 찾으면 1을 반환하고, 파일의 끝을 발견하면 0을 반환합니다.
답변2
귀하의 질문이 명확하지 않은 것 같습니다. 한 답변은 4줄을 삭제합니다(일치하는 두 줄과 다음 두 줄은 모든 것을 삭제합니다).하지만어울리는 라인...
원하는 내용을 추가하겠습니다. 일치하는 행 Name: 123
과 그 다음 행의 2개 행을 삭제합니다. 나는 다음을 사용하여 이 작업을 수행합니다 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개의 개별 명령으로 구성됩니다.
이 두 명령은 공백 문자로 시작하는 모든 줄
s///
에 적용됩니다 .-,. j
명령의 빈 정규식은 이전 명령의 표현식을 재사용하므로s
(정규식과 일치하는 줄에 하나 이상의 명령을 적용하는 데 사용됨) 명령이 첫 번째 공백을 제거합니다. 그런 다음 이 명령은 수정된 줄을 이전 줄과 연결합니다. 이렇게 하면 입력 데이터의 줄 바꿈이 효과적으로 취소됩니다.^
g
s
j
이 명령은
d
다음으로 시작하는 모든 줄에서 작동Name:
하고 제거합니다.마찬가지로,로 시작하는 줄이
SHA-256-Digest:
삭제됩니다.4번째 줄부터 빈 줄을 삭제하세요.
결과를 표시하기 위해 전체 버퍼를 표준 출력으로 인쇄합니다.
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