2355 votes

Comment supprimer d'un fichier texte, toutes les lignes qui contiennent une chaîne spécifique ?

Comment utiliser sed pour supprimer toutes les lignes d'un fichier texte qui contiennent une chaîne spécifique ?

3550voto

SiegeX Points 32614

Pour supprimer la ligne et imprimer la sortie sur la sortie standard :

sed '/pattern to match/d' ./infile

Pour modifier directement le fichier - ne fonctionne pas avec BSD sed :

sed -i '/pattern to match/d' ./infile

Idem, mais pour BSD sed (Mac OS X et FreeBSD) - ne fonctionne pas avec GNU sed :

sed -i '' '/pattern to match/d' ./infile

Pour modifier directement le fichier (et créer une sauvegarde) - fonctionne avec BSD et GNU sed :

sed -i.bak '/pattern to match/d' ./infile

18 votes

Merci, mais cela ne semble pas l'effacer du fichier, mais simplement imprimer le contenu du fichier texte sans cette chaîne.

130 votes

@A Clockwork : oui, vous devez rediriger la sortie soit vers un nouveau fichier avec quelque chose comme sed '/pattern to match/d' ./infile > ./newfile ou si vous voulez faire une modification sur place, vous pouvez ajouter l'option -i à sed comme dans sed -i '/pattern to match/d' ./infile . Notez que le -i nécessite GNU sed et n'est pas portable

2 votes

Comment puis-je savoir quelle version de sed j'ai ? GNU ou non GNU ?

728voto

kurumi Points 10096

Il existe de nombreuses autres façons de supprimer les lignes contenant une chaîne de caractères spécifique, à part sed :

AWK

awk '!/pattern/' file > temp && mv temp file

Ruby (1.9+)

ruby -i.bak -ne 'print if not /test/' file

Perl

perl -ni.bak -e "print unless /pattern/" file

Shell (bash 3.2 et plus)

while read -r line
do
  [[ ! $line =~ pattern ]] && echo "$line"
done <file > o
mv o file

GNU grep

grep -v "pattern" file > temp && mv temp file

Et bien sûr sed (l'impression de l'inverse est plus rapide que la suppression réelle) :

sed -n '/pattern/!p' file

4 votes

Comment supprimer une ligne particulière avec un motif et aussi la ligne immédiatement au-dessus ? J'ai une amende avec des milliers de lignes de ce type entre différentes données.

2 votes

Sous OS/X, la variante shell ne préserve pas les espaces en tête, mais la variante grep -v a bien fonctionné pour moi.

18 votes

Le site sed a un comportement différent, il ne fait que greps ! il devrait être quelque chose comme sed -n -i '/pattern/!p' file .

340voto

slashdottir Points 1143

Vous pouvez utiliser sed pour remplacer les lignes en place dans un fichier. Cependant, cela semble être beaucoup plus lent que d'utiliser grep pour l'inverse dans un second fichier, puis de déplacer le second fichier sur l'original.

par exemple

sed -i '/pattern/d' filename      

ou

grep -v "pattern" filename > filename2; mv filename2 filename

La première commande prend 3 fois plus de temps sur ma machine de toute façon.

32 votes

Voter votre réponse aussi, juste parce que vous avez essayé une comparaison de performance !

6 votes

+1 pour offrir l'option d'écraser le fichier courant avec la ligne grep.

0 votes

Pour une raison quelconque, la version mac os sed (BSD) n'accepte pas les noms de fichiers de sauvegarde de longueur zéro, mais lorsqu'on en fournit un, cela fonctionne.

112voto

Kevin Nguyen Points 83

La façon la plus simple de le faire, avec GNU sed :

sed --in-place '/some string here/d' yourfile

48voto

kenorb Points 2464

Vous pouvez envisager d'utiliser ex (qui est un éditeur standard Unix à base de commandes) :

ex +g/match/d -cwq file

où :

  • + exécute la commande Ex donnée ( man ex ), comme -c qui exécute wq (écrire et quitter)
  • g/match/d - Commande Ex pour effacer les lignes avec des données match voir : Puissance de g

L'exemple ci-dessus est une méthode conforme à POSIX pour l'édition en place d'un fichier, comme suit poste à Unix.SE et Les spécifications POSIX pour ex .


La différence avec sed c'est que :

sed est un S tream ED itor, et non un éditeur de fichiers. BashFAQ

À moins que vous n'appréciiez le code non portable, les surcharges E/S et d'autres effets secondaires néfastes. Donc, fondamentalement, certains paramètres (tels que in-place/ -i ) sont des extensions non standard de FreeBSD et peuvent ne pas être disponibles sur d'autres systèmes d'exploitation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X