![주문하다:](https://linux55.com/image/92559/%EC%A3%BC%EB%AC%B8%ED%95%98%EB%8B%A4%3A.png)
블록은 항상 00 PROGRAM으로 시작합니다.
XYZ로 끝나고 그 뒤에 빈 줄이 옵니다. XYZ는 이전 행 블록에도 나타나지만 이전 행 뒤에는 더 많은 데이터가 옵니다. 빈 줄 앞의 마지막 줄만 필요합니다. 내 의도와 일치하는 코드를 찾지 못했습니다. 이것이 누군가에게는 쉬운 대답이기를 바랍니다!
빈 줄 앞의 마지막 줄을 유지하고 싶습니다. 예를 들어:
000-12-22
AB1
00 PROGRAM
01 INQUIRY
03 XYZ
04 XYZ
blank line
LINE VALUE
00456
이 부분만 삭제하면 됩니다.
00 PROGRAM
01 INQUIRY
03 XYZ
답변1
이 유형의 범위는 다음과 같습니다.완벽한사용 사례 ex
. 나는 가지고있다ex
많이 썼다이 사이트에서는 스크립트 파일 편집을 위한 최고의 POSIX 도구입니다.
주문하다:
하나의 블록만 처리해야 하는 경우 다음을 사용하세요.
printf '%s\n' '/00 PROGRAM/' '.,/^$/-2d' x | ex file.txt
여러 블록이 가능한 경우 다음을 사용하세요.
printf '%s\n' 'g/00 PROGRAM/.,/^$/-2d' x | ex file.txt
테스트하려면 %p
다음을 대신 사용하세요 x
.
printf '%s\n' '/00 PROGRAM/' '.,/^$/-2d' %p | ex file.txt
printf '%s\n' 'g/00 PROGRAM/.,/^$/-2d' %p | ex file.txt
그러면 버퍼의 내용을 파일에 다시 저장하는 대신 전체 버퍼가 인쇄됩니다.
삽화:
[vagrant@localhost ~]$ cat file.txt
000-12-22
AB1
00 PROGRAM
01 INQUIRY
03 XYZ
04 XYZ
LINE VALUE
00456
[vagrant@localhost ~]$ printf '%s\n' '/00 PROGRAM/' '.,/^$/-2d' x | ex file.txt
[vagrant@localhost ~]$ cat file.txt
000-12-22
AB1
04 XYZ
LINE VALUE
00456
[vagrant@localhost ~]$
설명 및 의견:
를 사용할 수 있지만 ex -c 'editingcommands' filename
이것이 해결하는 것보다 더 많은 문제를 야기한다는 것을 발견했습니다. ex
오류가 발생하면 종료하는 대신 사용자 입력을 기다리면서 정지됩니다. 또한 ex
POSIX는 이를 수행할 수 있는 공통 기능을 보장하지 않기 때문에 이러한 방식으로 여러 명령을 전달하는 데 잠재적인 이식성 문제가 있습니다 .
대신 일반적으로 명령을 ex
from 으로 파이프합니다 printf
. 이를 통해 여러 명령을 형식 문자열을 사용하여 %s\n
쉽게 개행으로 구분할 printf
수 있으며, 오류가 발생하는 경우(예: 파일의 마지막 줄보다 큰 줄을 편집하려고 하는 경우) 파일이 중단되지 않고 그대로 유지됩니다.
실제로 파일을 편집하기 전에 명령을 테스트하기 위해 %p
마지막 명령으로 (전체 버퍼 인쇄)를 사용합니다. 그런 다음 명령을 약간 조정하고 원하는 정확한 파일 내용을 얻을 때까지 반복해서 실행할 수 있습니다. 결과에 만족하면 명령을 실행 %p
하도록 변경합니다.x
하나실제로 파일 변경 사항을 저장하는 데 더 많은 시간이 걸립니다.
이 질문에 대한 답으로 제가 내린 명령은 다음과 같습니다.
printf '%s\n' '/00 PROGRAM/' '.,/^$/-2d' x | ex file.txt
이 명령은 다음과 같이 새 줄로 구분 된 printf
세 개의 문자열을 인쇄합니다 ./00 PROGRAM/
.,/^$/-2d
x
[vagrant@localhost ~]$ printf '%s\n' '/00 PROGRAM/' '.,/^$/-2d' x
/00 PROGRAM/
.,/^$/-2d
x
[vagrant@localhost ~]$
이 세 줄은 ex
명령입니다.
ex
명령 개요
명령은 ex
주소(라인 기반)와 명령의 두 부분으로 구성됩니다.
주소가 하나만 있는 경우 커서는 해당 주소(해당 줄로 이동)로 이동합니다.
명령만 있는 경우 현재 행이 주소로 사용됩니다.
주소는 일반적으로범위— 주소, 쉼표, 다른 주소 순입니다. 첫 번째 주소부터 두 번째 주소까지의 모든 라인을 나타냅니다.
주소는 행 번호일 수 있지만 반드시 그럴 필요는 없습니다. "이 정규식과 일치하는 현재 줄 다음 줄"을 의미하는 검색 패턴일 수도 있습니다. 앞으로 검색할 수도 있고 뒤로 검색할 수도 있습니다.
foo
"이 인스턴스 앞의 두 줄은 현재 줄 바로 앞의 인스턴스 뒤에 발생합니다"라는 주소를 쓸 수도 있습니다 . bar
이것은 다음과 같습니다:?bar?/foo/-2
단계별로
명령 /00 PROGRAM/
은 단지 주소이므로 "'00 PROGRAM' 패턴의 첫 번째 인스턴스로 커서를 이동하십시오"라는 의미입니다.
이 명령은 .,/^$/-2d
두 부분으로 구성됩니다. 마지막은 d
"삭제"를 의미하는 명령입니다. 이제 남은 것은 주소뿐이다.
첫 번째 문자 .
는 현재 행을 나타내는 특수 주소입니다.
패턴은 빈 줄(줄의 시작 과 줄의 끝 ) /^$/
에 대한 정규식입니다 . 이 경우 현재 커서 위치 다음의 빈 줄을 의미합니다.^
$
-2
이는 "두 줄 뒤로"를 의미합니다 .
글쎄요, 이것이 .,/^$/-2d
의미하는 바는 "현재 줄에서 다음 빈 줄 위의 두 줄까지 줄을 삭제합니다."입니다.
x
간단히 말해서, 버퍼 내용을 파일에 저장하고 편집기를 종료하십시오.
이것이 당신에게 도움이 되기를 바랍니다. ex
매우 강력한 텍스트 편집 도구입니다. vi
"비주얼 에디터"의 전신 입니다 . 모든 명령을 ex
실행할 수도 있습니다.vi
답변2
수정된 질문에 답하세요
이 테스트 파일을 고려해 보겠습니다.
$ cat File2
000-12-22
AB1
00 PROGRAM
01 INQUIRY
03 XYZ
04 XYZ
LINE VALUE
00456
다음 명령을 시도해 보세요.
$ sed '/00 PROGRAM/,/^$/{/./{h;d}; x; p; x;}' File2
000-12-22
AB1
04 XYZ
LINE VA
루에 00456
원래 질문에 답하다
00 PROGRAM
내가 올바르게 이해했다면 빈 줄이 포함된 줄로 시작하고 끝나는 여러 선취권 세트가 포함된 파일이 있는 것입니다 XYZ
. 이 경우 다음을 시도하십시오.
sed -n '/00 PROGRAM/,/^$/{/./{h;d}; x;/XYZ/p}' file
예
다음 예제 파일을 고려해보세요.
$ cat file
00 PROGRAM
some
XYZ discard this
data
XYZ keep this
other
00 PROGRAM
more
XYZ keep this also
end
이는 XYZ
블록의 빈 줄 앞의 줄만 유지합니다 00 PROGRAM
.
$ sed -n '/00 PROGRAM/,/^$/{/./{h;d}; x;/XYZ/p}' file
XYZ keep this
XYZ keep this also
선택하다
아마도 그룹 외부의 모든 행을 유지하고, 일치하는 경우 그룹의 비어 있지 않은 마지막 행도 유지하고 싶을 것입니다 XYZ
. 이 경우:
$ sed '/00 PROGRAM/,/^$/{/./{h;d}; x;/XYZ/!d}' file
XYZ keep this
other
XYZ keep this also
end