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?

Folkert van Heusden
la source
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.

αғsнιη
la source
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/'
jlliagre
la source
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//'
jfg956
la source
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.

mikeserv
la source