J'essaie de supprimer les messages d'erreur imprimés dans mon fichier. J'ai ceci:
addr:1122c:1234:
addr:11230:5678:
addr:11223:01Error:abcdef(x, y) = z, value = a
Error:hijklm(v, q) = w, value = b
Error:nopqrst(x, y) = z, value = d
Error:uvwxyz(l, m) = z, value = e
Error:1234(u, t) = z, value = f
Error:567(r, s) = z, value = g
err_total = 9846, err_sub = 0, err_mask = 239
1 Duration: xyz, abc
0 Duration: pqr, def
23:
addr:11238:4567:
addr:1123c:8901:
J'ai besoin de supprimer tous les messages d'erreur jusqu'à la prochaine adresse apparaît. La sortie requise est:
addr:1122c:1234:
addr:11230:5678:
addr:11223:0123:
addr:11238:4567:
addr:1123c:8901:
J'ai essayé:
sed -i "/\bError\b/d" file_name
Mais cela supprime les lignes commençant par Erreur et ne supprime pas la ligne où la chaîne d'erreur a commencé au milieu.
Je suis nouveau dans les expressions régulières, une explication serait vraiment utile.
Edit: J'utilise sed -i '/Error/,/addr/d' filename
mais cela supprime toute la ligne et ne donne pas ce que je recherche.
sed
n'est pas vraiment bon dans la correspondance multiligne.
Vous pouvez le tromper pour faire ce que vous voulez, mais alors imo Perl
est plus facile à gérer.
Essaye ça:
Perl -pe 'BEGIN{undef $/;}; s/Error.*?(^[0-9]* Duration: [^\n]*\n)+//smg;'
Explication:
BEGIN { do_something; }
: Faire quelque chose une fois au débutundef $/
: Ignorer les fins de lignes///
RemplaçantError.*
Correspond à n'importe quelle chaîne commençant par "Erreur".?
Rendre la correspondance précédente ungreedy, car elle s'arrête à la correspondance suivante ou, dans ce cas, au groupe correspondant ...()+
Créez un groupe correspondant, qui doit être mis en correspondance au moins une fois (+
).^[0-9]* Duration: [^\n]*\n
: Fait correspondre la ligne entière avec Duration, y compris.( via )
Plutôt que de supprimer les lignes "Error:
", pourquoi ne pas extraire uniquement les lignes souhaitées avec:
grep -E '^ addr:' file_name | sed -e 's/Error:.*//'
Cela générera le résultat recherché:
$ cat file_name | grep -v \
-e '^Error:' \
-e '^err_total' \
-e '^.*[0-9] Duration:' | \
sed ':a;$!N;s/Error:.*\n\(.*[0-9]\):/\1:/;ta;P;D'
Frist supprime tous les éléments Error
, err_total
et 12345 Duration:
. Recherchez ensuite le Error: ...
interrompant votre sortie, supprimez la nouvelle ligne (\n
), recherchez la prochaine occurrence d’un nombre (.*[0-9]:
) et ajoutez-la à la ligne en cours.