Comment utiliser sed pour supprimer toutes les lignes d'un fichier texte contenant une chaîne spécifique?
Comment utiliser sed pour supprimer toutes les lignes d'un fichier texte contenant une chaîne spécifique?
Pour supprimer la ligne et imprimer la sortie en sortie standard:
sed '/pattern to match/d' ./infile
Pour modifier directement le fichier:
sed -i '/pattern to match/d' ./infile
Pour modifier directement le fichier (et créer une sauvegarde):
sed -i.bak '/pattern to match/d' ./infile
Pour les utilisateurs de Mac OS X:
sed -i '' '/pattern/d' ./infile
il y a beaucoup d'autres façons de supprimer des lignes avec une chaîne spécifique en plus sed
awk
awk '!/pattern/' file > temp && mv temp file
Rubis (1.9+)
ruby -i.bak -ne 'print if not /test/' file
Perl
perl -ni.bak -e "print unless /pattern/" file
Shell (bash3.2 +)
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
Vous pouvez utiliser sed pour remplacer les lignes en place dans un fichier. Cependant, il semble être beaucoup plus lent que d'utiliser grep pour l'inverse dans un second fichier et ensuite déplacer le deuxième 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.
Le moyen facile de le faire, avec GNU sed
:
sed --in-place '/some string here/d' yourfile
Vous pouvez envisager d'utiliser ex
(qui est un éditeur basé sur une commande UNIX standard):
ex +g/match/d -cwq file
où:
+
exécute la commande Ex donnée (man ex
), pareil que -c
qui exécute wq
(écrire et quitter)g/match/d
- Commande Ex pour supprimer des lignes avec donnée match
, voir: Puissance de gL'exemple ci-dessus est la méthode POSIX-conforme pour l'édition sur place d'un fichier selon cette poster chez Unix.SE et Spécifications POSIX pour ex
.
La différence avec sed
est-ce:
sed
est un Stream EDItor, pas un éditeur de fichiers.BashFAQ
sauf si vous appréciez le code non portable, les frais généraux d'E / S et d'autres effets secondaires. Donc, fondamentalement, certains paramètres (tels que in-place /-i
) sont des extensions FreeBSD non standard et peuvent ne pas être disponibles sur d'autres systèmes d'exploitation.
Je me débattais avec ça sur Mac. De plus, j'avais besoin de le faire en utilisant un remplacement variable. J'ai donc utilisé:
sed -i '' "/$pattern/d" $file
où $file
est le fichier où la suppression est nécessaire et $pattern
est le motif à apparier pour la suppression.
Choisi le ''
de cette commentaire.
La chose à noter ici est l'utilisation de double citation dans "/$pattern/d"
. La variable ne fonctionne pas lorsque nous utilisons un guillemet simple.
Pour obtenir un résultat in situ avec grep
tu peux le faire:
echo "$(grep -v "pattern" filename)" >filename
J'ai fait un petit benchmark avec un fichier qui contient environ 345 000 lignes. Le chemin avec grep
semble être environ 15 fois plus rapide que le sed
méthode dans ce cas.
J'ai essayé à la fois avec et sans le paramètre LC_ALL = C, il ne semble pas changer les timings de manière significative. La chaîne de recherche (CDGA_00004.pdbqt.gz.tar) se trouve quelque part au milieu du fichier.
Voici les commandes et les horaires:
time sed -i "/CDGA_00004.pdbqt.gz.tar/d" /tmp/input.txt
real 0m0.711s
user 0m0.179s
sys 0m0.530s
time perl -ni -e 'print unless /CDGA_00004.pdbqt.gz.tar/' /tmp/input.txt
real 0m0.105s
user 0m0.088s
sys 0m0.016s
time (grep -v CDGA_00004.pdbqt.gz.tar /tmp/input.txt > /tmp/input.tmp; mv /tmp/input.tmp /tmp/input.txt )
real 0m0.046s
user 0m0.014s
sys 0m0.019s
SED:
AWK:
GREP:
Vous pouvez l'utiliser aussi
grep -v 'pattern' filename
ici -v n'imprimera que votre modèle (ce qui signifie Inverser la correspondance)