3 votes

Enlever une seule ligne de plusieurs fichiers

J'essaie de supprimer une chaîne de caractères de plusieurs fichiers texte sur l'un de nos serveurs. La chaîne est identique dans tous ces fichiers et je peux l'exécuter :

grep -r -l 'string'  

pour obtenir la liste des fichiers, mais je ne sais pas comment faire pour que les fichiers soient édités et réécrits à leur emplacement d'origine. Cela semble être un travail pour sed mais je ne suis pas sûr de savoir comment gérer la sortie.

5voto

Ryan Sampson Points 2898

find -type f -print0 | xargs -0 -n 1 sed -i /string/d fera l'affaire, en gérant les espaces dans les noms de fichiers et les frufru arbitrairement imbriqués, puisque apparemment les gens ne sont pas capables de développer * par eux-mêmes.

3voto

Corin Blaikie Points 6223

Voici mon script pour ce genre de chose, que j'appelle remove_line :

#!/usr/bin/perl

use IO::Handle;

my $pat = shift(@ARGV) or
        die("Usage: $0 pattern files\n");
$pat = qr/$pat/;
die("Usage $0 pattern files\n")
        unless @ARGV;

foreach my $file (@ARGV) {
        my $io = new IO::Handle;
        open($io, $file) or
                die("Cannot read $file: $!\n");
        my @file = <$io>;
        close($io);
        foreach my $line (@file) {
                if($line =~ /$pat/) {
                        $line = '';
                        $found = 1;
                        last;
                }
        }
        if($found) {
                open($io, ">$file") or
                        die("Cannot write $file: $!\n");
                print $io @file;
                close($io);
        }
}

Alors vous le faites remove_line 'string' les fichiers de votre liste.

Les avantages de cette méthode par rapport à l'utilisation sed c'est que vous n'avez pas à vous soucier du comportement dépendant de la plateforme de l'application sed -i et vous pouvez utiliser Perl regex pour le motif de correspondance.

1voto

mfinni Points 35332

Ugh. Je ne suis pas du tout un assistant Shell, mais je regarderais un pipe vers xargs et ensuite sed pour enlever la ligne avec la chaîne en question.

Un petit coup d'œil sur Google me fait penser que cela pourrait faire de Bob votre oncle par alliance - assez proche pour y arriver en tout cas.

grep -r -l 'string'  | xargs sed '/string/d'

0voto

leonho Points 2787

Ummmmmm, c'est un perl one-liner grâce à la joli -i drapeau pour filtrage en place des fichiers d'entrée !

   **perl -ni.bak -e 'print unless /pattern.to.remove/' file1 file2 ...**

Dans le contexte...

% echo -e 'foo\ngoo\nboo' >test
% perl -ni.bak -e 'print unless /goo/' test
% diff test*
--- test 2010-01-06 05:09:13.503334739 -0800
+++ test.bak 2010-01-06 05:08:28.313583066 -0800
@@ -1,2 +1,3 @@
 foo
+goo
 boo

voici la référence rapide rognée sur l'incantation perl utilisée...

% perl --help
Usage: perl [switches] [--] [programfile] [arguments]
  -e program        one line of program (several -e's allowed, omit programfile)
  -i[extension]     edit <> files in place (makes backup if extension supplied)
  -n                assume "while (<>) { ... }" loop around program

et pour un crédit supplémentaire, vous pouvez utiliser touch -r file.bak file pour copier l'ancien horodatage dans le nouveau fichier. Les inodes seront différents, cependant, et des choses étranges peuvent se produire si vous avez des liens durs dans le mélange... vérifiez les docs si vous êtes un utilisateur de l'Internet. qui ont motivé pour couvrir vos traces... Hmmmmm, quelle était votre demande déjà ?

-1voto

hookenz Points 13952

N'oubliez pas l'option -v dans grep qui inverse le sens

grep -v -r -l 'string' 

Frok fom grep man page :

-v, --invert-match
Invert the sense of matching, to select non-matching lines.  (-v is specified by POSIX.)

Vous pouvez alors passer cette information dans la commande find comme ceci

find -name -exec grep -v -r -l 'string' {} \ ;

Et cela se rapproche de ce que vous voulez... mais bien sûr, vous devrez réécrire le résultat dans le fichier d'origine...

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X