sed: supprime toutes les occurrences d'une chaîne sauf la première


14

J'ai un fichier journal avec des horodatages. Parfois, il y a plusieurs horodatages sur une seule ligne. Maintenant, je voudrais supprimer tous les horodatages d'une ligne mais garder le premier.

Je peux le faire, s/pattern//2mais cela ne supprime que la deuxième occurrence et sedne permet pas quelque chose comme s/pattern//2-.

Aucune suggestion?


J'aurais dû dire que c'est le sed de busybox. Désolé.
Folkert van Heusden

Réponses:


4

Avec GNU sed:

sed 's/pattern//2g'

Le 2spécifie que le deuxième motif et tout le reste gdoivent être supprimés. Donc, cela gardera le premier.


1
Ce que Cygwin a (un port, apparemment) et MacOS ne possède pas. Achh! Cette solution est tellement plus élégante.
r_alex_hall

7

Cela devrait fonctionner (remplacez _ par quelque chose d'autre en cas de conflit avec vos journaux):

sed -e 's/pattern/_&/1' -e 's/\([^_]\)pattern//g' -e 's/_\(pattern\)/\1/'

1
si vous voulez un délimiteur unique, utilisez \n.
mikeserv

5
sed -e ':begin;s/pattern//2;t begin'

ou sans le goto sed:

sed -e 's/\(pattern\)/\1\n/;h;s/.*\n//;s/pattern//g;H;g;s/\n.*\n//'

Les solutions génériques à retirer de la nième position (3 par exemple) sont:

sed -e ':begin;s/pattern//4;t begin'
sed -e 's/\(pattern\)/\1\n/;h;s/.*\n//3;s/pattern//g;H;g;s/\n.*\n//'

1

Une légère variation sur la réponse de @ jillagre (modifiée pour la robustesse) pourrait ressembler à:

sed 's/p\(attern\)/p\n\1/;s///g;s/\n//'

... mais dans certains cas, sedvous devrez peut-être remplacer le ndans le côté droit de la première s///instruction de substitution par un caractère littéral \newline.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.