Remover parágrafo do arquivo

4

Eu tenho um arquivo ( file.php ) como este:

...
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

Estou tentando escrever um script bash para excluir um dos parágrafos.

Digamos que eu queira excluir o usuário foo do file.php . Depois de executar o script, ficaria assim:

...
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

Como eu poderia fazer isso? Eu pensei em usar sed , mas isso só parece ser apropriado para um forro?

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

E eu não poderia fazer isso para cada linha individual, já que a maioria das linhas do parágrafo não é única! Alguma idéia?

    
por maxisme 25.03.2015 / 18:26

2 respostas

5

Na verdade, sed também pode ter intervalos. Este comando irá deletar todas as linhas entre Match user foo e a primeira linha vazia (inclusive):

$ 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

Pessoalmente, no entanto, eu faria isso usando o modo de parágrafo do perl ( -00 ) que tem o benefício de remover as linhas em branco iniciais:

$ 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

Em ambos os casos, você pode usar -i para editar o arquivo no lugar (isso criará um backup do original chamado file.bak ):

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

ou

perl -i.bak -00ne 'print unless /Match user foo/' file 
    
por 25.03.2015 / 18:31
1

Ligeiramente mais complicado que a resposta sed de terdon,

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

produz quase exatamente o mesmo resultado que a resposta de 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

isto é, elimina (suprime) todas as linhas começando com o que corresponde a foo up para a primeira linha subsequente que contém apenas espaços em branco. Linhas 8, 9 e 10, que estão em branco no arquivo de entrada file.php (entre user foo e user bar ) saem na saída. Por outro lado, a resposta de terdon exclui todas as linhas começando com o que corresponde a foo up através de a primeira linha subsequente que contém apenas espaços em branco; então a linha 8 é deletada, mas 9 e 10 passam.

Estes não são exatamente o que o usuário solicitou.

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

é. (Isso é dividido em várias linhas para facilitar a leitura; poderia ser inserido tudo em uma linha.) Quando ele vê foo , entra em modo de supressão # 1 ( suppress=1 ). Quando vir uma linha em branco enquanto estiver no modo de supressão # 1, muda para o modo de supressão # 2. Quando vir uma linha não em branco enquanto estiver no modo de supressão # 2, muda para o modo 0. Finalmente, faz o óbvio - linhas de impressão que não são suppress ed.

    
por 26.03.2015 / 03:22