중복된 경우 패턴과 일치하는 행 삭제

중복된 경우 패턴과 일치하는 행 삭제

구성 파일이 있다고 가정해 보겠습니다.

[main]
foo = bar
[option]
opt1 = opt2
opt3 = opt4
[extra]
[footer]
[tail]
print = true
[end]

[text]아래 옵션이 있는 경우에만 제목()을 인쇄하고 싶습니다. 따라서 출력은 다음과 같아야 합니다.

[main]
foo = bar
[option]
opt1 = opt2
opt3 = opt4
[tail]
print = true

답변1

일반적으로 가독성을 위해 여러 줄로 작성하지만 한 줄을 요청했기 때문에 다음과 같습니다.

perl -ne '$head = $_ and next if /^\[/; $head and print $head and undef $head; print'

답변2

휴대용 sed; gnu sed가 아니어야 합니다. 파일을 conf로 두십시오.

 sed -E 'N;/^\[.+\]\n\[.+\]$/!P;D' conf

Gnu sed가 기본 휴대용으로 설정한 경우

sed --posix -E 'N;/^\[.+\]\n\[.+\]$/!P;D' conf

답변3

$ awk '/^\[/ { head = $0; next } head != "" { print head; head = "" } { print }' file
[main]
foo = bar
[option]
opt1 = opt2
opt3 = opt4
[tail]
print = true

프로그램 awk은 찾은 각 헤더를 변수에 저장 head하고 즉시 다음 입력 줄로 이동합니다.

만약 라인이아니요헤더 행, head변수에 무언가가 포함되어 있으면 헤더를 출력합니다. 그런 다음 현재 행을 출력합니다.

이것은 거의 문자 그대로의 번역입니다.에드 그린의 답변입력하다 awk.


다소 직접적으로 다음과 같이 변환됩니다 sed. 여기서는 아래와 같이 최신 헤더를 유지하기 위해 공간이 예약되어 있습니다.

/^\[/ {
    h;    # store header in hold space (overwriting)
    d;    # delete pattern space, start next cycle
}

x;                   # swap with hold space
/./ { p; s///g; };   # if non-empty, print and empty
x;                   # swap with hold space

또는 단일 라이너로

$ sed -e '/^\[/{ h;d; }' -e 'x; /./{ p;s///g; }' -e x file
[main]
foo = bar
[option]
opt1 = opt2
opt3 = opt4
[tail]
print = true

또 다른 짧은 sed변형은 파일 끝에 빈 섹션/헤더가 있다는 사실에 의존합니다.

$ sed -n -e'/^\[/{ x;/\n/p;d; }' -e H file
[main]
foo = bar
[option]
opt1 = opt2
opt3 = opt4
[tail]
print = true

이렇게 하면 헤더와 이와 관련된 기타 행이 예약된 공간에 저장됩니다. 새 헤더가 발견되면 예약된 공간이 교체되고 개행이 확인됩니다. 찾으면 인쇄하세요. 다른 줄은 단순히 예약된 공간에 추가됩니다.

왜냐하면 awk, 이것은 다음과 같습니다

awk '/^\[/ { if (sect ~ ORS) print sect; sect = $0; next } { sect = sect ORS $0 }' file

관련 정보