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
편집되지 않은 줄을 인쇄합니다.