파일에서 단락 제거

파일에서 단락 제거

file.php다음과 같은 파일이 있습니다( ).

...
Match user foo
        ChrootDirectory /NAS/foo.info/
        ForceCommand internal-sftp
        AllowTcpForwarding no
        GatewayPorts no
        X11Forwarding no



Match user bar
        ChrootDirectory /NAS/bar.co.uk/
        ForceCommand internal-sftp
        AllowTcpForwarding no
        GatewayPorts no
        X11Forwarding no



Match user baz
        ChrootDirectory /NAS/baz.com/
        ForceCommand internal-sftp
        AllowTcpForwarding no
        GatewayPorts no
        X11Forwarding no

단락 중 하나를 삭제하기 위해 bash 스크립트를 작성하려고 합니다.


foo에서 스크립트를 실행 하고 싶다고 가정해 보겠습니다 file.php.

...
Match user bar
        ChrootDirectory /NAS/bar.co.uk/
        ForceCommand internal-sftp
        AllowTcpForwarding no
        GatewayPorts no
        X11Forwarding no



Match user baz
        ChrootDirectory /NAS/baz.com/
        ForceCommand internal-sftp
        AllowTcpForwarding no
        GatewayPorts no
        X11Forwarding no

어떻게 해야 하나요? 사용을 고려했지만 sed라이너 하나만 맞는 것 같나요?

sed -i 's/foo//g' file.php

단락에 있는 대부분의 줄이 고유하지 않기 때문에 모든 줄에 대해 이 작업을 수행할 수 없습니다! 어떤 아이디어가 있나요?

답변1

실제로 sed범위를 선택할 수도 있습니다. 이 명령은 Match user foo첫 번째 빈 줄(포함) 사이의 모든 줄을 삭제합니다 .

$ sed '/Match user foo/,/^\s*$/{d}' file


Match user bar
        ChrootDirectory /NAS/bar.co.uk/
        ForceCommand internal-sftp
        AllowTcpForwarding no
        GatewayPorts no
        X11Forwarding no



Match user baz
        ChrootDirectory /NAS/baz.com/
        ForceCommand internal-sftp
        AllowTcpForwarding no
        GatewayPorts no
        X11Forwarding no

그러나 개인적으로 나는 -00선행 빈 줄을 제거하는 이점이 있는 Perl의 단락 모드( )를 사용하여 이 작업을 수행합니다.

$ perl -00ne 'print unless /Match user foo/' file
Match user bar
        ChrootDirectory /NAS/bar.co.uk/
        ForceCommand internal-sftp
        AllowTcpForwarding no
        GatewayPorts no
        X11Forwarding no

Match user baz
        ChrootDirectory /NAS/baz.com/
        ForceCommand internal-sftp
        AllowTcpForwarding no
        GatewayPorts no
        X11Forwarding no

두 경우 모두 -i파일의 내부 편집을 사용할 수 있습니다(이렇게 하면 이름이 원본 파일의 백업이 생성됨 file.bak).

sed -i.bak '/Match user foo/,/^\s*$/{d}' file

또는

perl -i.bak -00ne 'print unless /Match user foo/' file 

답변2

terdon의 답변보다 조금 더 복잡합니다 sed.

awk '/foo/ {suppress=1} /^\s*$/ {suppress=0} !suppress' file.php

terdon의 답변과 거의 동일한 결과를 생성합니다.

...



Match user bar
        ChrootDirectory /NAS/bar.co.uk/
        ForceCommand internal-sftp
        AllowTcpForwarding no
        GatewayPorts no
        X11Forwarding no



Match user baz
        ChrootDirectory /NAS/baz.com/
        ForceCommand internal-sftp
        AllowTcpForwarding no
        GatewayPorts no
        X11Forwarding no

즉, 일치하는 줄부터 시작하는 모든 foo 줄을 삭제(억제)합니다.도착하다공백만 포함된 첫 번째 후속 줄입니다. 입력 파일의 8, 9, 10행 file.php( user foo과 사이) user bar은 비어 있으며 출력에 나타납니다. 대조적으로 terdon의 답변은 일치하는 줄로 foo 시작하는 모든 줄을 제거합니다.통과하다첫 번째 후속 라인에는 공백만 포함되어 있으므로 8행은 삭제되지만 9행과 10행은 남아 있습니다.

이는 정확히 사용자가 요구하는 것이 아닙니다.

awk '/foo/ {suppress=1}
     /^\s*$/ && suppress==1 {suppress=2}
     /[^\s]/ && suppress==2 {suppress=0}
     !suppress' file.php

예. (가독성을 높이기 위해 여러 줄로 나누어서 한 줄에 모두 입력할 수 있습니다.) 이를 발견하면 억제 모드 #1( ) foo로 들어갑니다 . suppress=1억제 모드 #1에서 빈 줄이 보이면 억제 모드 #2로 전환됩니다. 억제 모드 #2에서 공백이 아닌 줄이 보이면 모드 0으로 전환됩니다. 마지막으로, 이는 명백한 작업을 수행합니다. 즉, suppress편집되지 않은 줄을 인쇄합니다.

관련 정보