Je veux supprimer toutes les lignes d’un fichier contenant le mot “test”, mais si cette ligne contient “test @”, je ne souhaite pas la supprimer.
Il y a probablement une manière géniale de le faire avec sed mais je me bats, j’ai essayé d’écrire une boucle de bash en utilisant sed mais c’est probablement stupide.
filetest=/tmp/filetest filetest_tmp=/tmp/filetest.tmp> $filetest_tmp fi done < $filetest cp $syslog_tmp $filetest
Comme vous pouvez le constater, je suis un newb à ceci 🙁
sed -e '/test/{/test@/!d;}'
Le premier motif correspond aux lignes contenant «test»; le second motif supprime les lignes à moins qu’elles ne correspondent à «test @».
Testé sur le fichier de données:
aaaa bbbtestbbb ccctest@ccc test! dddd
Sortie:
aaaa ccctest@ccc dddd
Cela semble répondre à vos exigences.
Utilisez grep
:
grep -v 'test[^@]' infile
En général, grep
imprime les lignes correspondantes, mais -v
indique d’imprimer des lignes non correspondantes.
L’expression régulière correspond à toute occurrence de “test” qui est suivie de tout sauf d’un “@”. Cela ne pose aucun problème si vous n’avez pas à vous attendre à un «test» à la fin d’une ligne. Si tel est le cas, utilisez
grep -E -v 'test([^@]|$)'
Je ne pense pas que cela vaille la peine de comprendre pourquoi votre solution ne fonctionne pas, car elle est brisée à bien des égards.
Si vous retournez votre question un peu, cela devient:
Comment filtrer toutes les lignes d’un fichier contenant la chaîne ‘test @’ ou ne contenant pas la chaîne ‘test’.
Cela peut par exemple se faire en awk comme ceci:
awk '!/foo/ || /foo@/' testfile
La réponse de Jonathan marche aussi, je voulais juste vous donner une version alternative.
Il n’y a pas besoin de fichier tmp si vous utilisez ed
!
# cf. http://wiki.bash-hackers.org/howto/edit-ed cat <<-'EOF' | ed -s file H ,g/test$/d ,g/test[^@]/d wq EOF