Comment puis-je supprimer une certaine ligne d'un fichier avec Perl?

1

Comment pourrais-je supprimer la ligne

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

à partir d'un fichier par une commande perl dans un script ksh?

J'ai essayé:

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

Mais j'ai eu:

Unmatched [ in regex; marked by <-- HERE in m/[ <-- HERE [ -f / at -e line 1.
Diane
la source

Réponses:

1

[, ., Et /ont une signification particulière dans une expression régulière. Vous devez leur échapper:

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

EDIT: attention, cela ne supprimera pas la ligne mais simplement le texte que vous avez dans la regex. Si c'est le cas, il restera une ligne blanche.

Version plus lisible (utilisez des crochets pour définir l'expression rationnelle de manière à ne pas avoir à vous échapper /):

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

Mais, puisque vous vous interrogez sur un script shell, pourquoi utiliser Perl et non grep -v( --invert-match)?

grep -v '[[ -f /var/tmp/Li.ksh ]] && /var/tmp/Li.ksh' /etc/tl.conf
Matteo
la source
Je ne veux pas écrire dans un autre fichier comme /etc/tl.conf, je veux éditer uniquement le fichier /var/tmp/tl.conf, à propos du perl semble bien, mais j'ai besoin d'une option plus simple, vous avez souvent utilisé "\" les lignes !
Diana
@ Diana Ok alors échappez les caractères spéciaux comme suggéré.
Matteo
Peut-être avez-vous une autre astuce en Perl pour ne pas utiliser le "\"?
Diana
@diana Il y a quelques astuces, mais en général, vous devez échapper des caractères spéciaux si vous souhaitez utiliser une expression régulière.
Matteo
1
@diana, @Matteo: vous pouvez utiliser \Qpour échapper à tous les caractères spéciaux suivants. Cela évite d’insérer tous ces caractères "\".
RedGrittyBrick
1

Fichier avant

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

Commande (en utilisant \ Q pour ignorer le caractère spécial des caractères spéciaux dans l'expression régulière)

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

Fichier après

$ cat t.txt
aaa
bbb

Remarque: le
changement -ià -i.baksi vous voulez perl faire une sauvegarde du fichier avant les modifications.

Vous pouvez également le faire de cette manière (en utilisant un simple test d’égalité de texte, sans regex).

$ perl -i -lne 'print unless $_ eq q([[ -f /var/tmp/Li.ksh ]] && /var/tmp/Li.ksh)' t.txt
RedGrittyBrick
la source
+1 pour les deux eqet\Q
Glenn Jackman
0

Je pense avoir obtenu quelque chose qui fonctionnera pour vous. En gros, je lis dans le fichier actuel et édite une version "modifiée" du fichier moins la ligne correspondante (celle mentionnée dans la question). Cela semble fonctionner pour moi quand je le teste. S'il vous plaît s'il vous plaît ne pas essayer ceci jusqu'à ce que vous faites une sauvegarde au cas où il va mal.

voici le code, modifiez le nom du fichier en fonction de vos besoins, puis exécutez le script "devrait" fonctionner.

Ce n'est pas très joli mais ça marche.

#!/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;
ianc1215
la source