Como excluo uma determinada linha de um arquivo com Perl?

1

Como eu excluiria a linha

[[ -f /var/tmp/Li.ksh ]] && /var/tmp/Li.ksh

de um arquivo por um comando perl em um script ksh?

Eu tentei:

perl -i -pe "s/[[ -f /var/tmp/Li.ksh ]] && /var/tmp/Li.ksh//" /etc/tl.conf 

Mas eu tenho:

Unmatched [ in regex; marked by <-- HERE in m/[ <-- HERE [ -f / at -e line 1.
    
por diana 16.11.2011 / 09:57

3 respostas

1

[ , . , e / têm um significado especial em uma expressão regular. Você tem que escapar deles:

perl -i -pe "s/\[\[\ -f\ \/var\/tmp\/Li\.ksh\ \]\]\ &&\ \/var\/tmp\/Li\.ksh//" 

EDIT: cuidado que isso não irá excluir a linha, mas apenas remover o texto que você tem na regex. Se se a linha inteira permanecer uma linha em branco.

Versão mais legível (use colchetes para definir o regex para que você não tenha que escapar de / ):

perl -i -pe "s{\[\[ -f /var/tmp/Li.ksh \]\] && /var/tmp/Li\.ksh}{}"

Mas, como você está perguntando sobre um script de shell, por que usar Perl e não grep -v ( --invert-match )?

grep -v '[[ -f /var/tmp/Li.ksh ]] && /var/tmp/Li.ksh' /etc/tl.conf
    
por 16.11.2011 / 10:04
1

Arquivo antes

$ cat t.txt
aaa
[[ -f /var/tmp/Li.ksh ]] && /var/tmp/Li.ksh
bbb

Comando (usando \ Q para ignorar o especialismo de caracteres especiais na expressão regular)

$ perl -i -lne 'print unless m{\Q[[ -f /var/tmp/Li.ksh ]] && /var/tmp/Li.ksh}' t.txt

Arquivo após

$ cat t.txt
aaa
bbb

Nota:
Altere -i para -i.bak se você quiser que o perl faça um backup do arquivo antes das alterações.

Você também pode fazer isso dessa maneira (usando um teste de igualdade de texto simples, sem regex).

$ perl -i -lne 'print unless $_ eq q([[ -f /var/tmp/Li.ksh ]] && /var/tmp/Li.ksh)' t.txt
    
por 16.11.2011 / 11:43
0

Acho que tenho algo que funcionará para você, basicamente estou lendo no arquivo atual e exibindo uma versão "modificada" do arquivo menos a linha correspondente (a mencionada na pergunta). Parece funcionar para mim quando eu testo. Por favor, por favor, NÃO tente isso até que você faça um backup apenas no caso de dar errado.

aqui está o código, altere o nome do arquivo para atender às suas necessidades e, em seguida, execute o script que "deve" funcionar.

Não é muito bonito, mas funciona.

#!/usr/bin/perl
use strict;
use warnings;

my $in_file = "sample.txt";
my $out_file = "control.txt";

open INFILE , "<", $in_file;
open OUTFILE,  ">", $out_file;

my @array;

while (<INFILE>) {

    push @array, $_;

}

foreach my $line (@array) {

    if ( $line =~ /(\"\[\[\s*\-f\s*\/var\/tmp\/Li\.ksh\s*\]\]\s*\&\&\s*\/var\/tmp\/Li.ksh\")/xm ) {

        print "I have ommited the following line $1\n";

    } else {

        print OUTFILE "$line";

    }

}

close INFILE;
close OUTFILE;
    
por 16.11.2011 / 10:41