sed: elimina todas las apariciones de una cadena excepto la primera


14

Tengo un archivo de registro con marcas de tiempo. Ocasionalmente, hay varias marcas de tiempo en una línea. Ahora me gustaría eliminar todas las marcas de tiempo de una línea, pero conservar la primera.

Puedo hacerlo, s/pattern//2pero eso solo elimina la segunda ocurrencia y sedno permite algo así s/pattern//2-.

¿Alguna sugerencia?


Debería haber dicho que es el sed de busybox. Lo siento por eso.
Folkert van Heusden

Respuestas:


4

Con GNU sed:

sed 's/pattern//2g'

El 2especifica que el segundo patrón y todo el resto gdeben eliminarse. Entonces esto mantendrá el primero.


1
Qué Cygwin tiene (un puerto de, aparentemente) y MacOS no. Achh! Esta solución es mucho más elegante.
r_alex_hall

7

Esto debería funcionar (reemplace _ por algo más si choca con sus registros):

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

1
si alguna vez quieres un delimitador único, úsalo \n.
mikeserv

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

o sin el sed goto:

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

Las soluciones genéricas para eliminar de la enésima posición (3 por ejemplo) son:

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

Una ligera variación en la respuesta de @ jillagre (modificada para robustez) podría verse así:

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

... pero en algunos seds puede que necesite reemplazar el nen el lado derecho de la primera s///declaración de sustitución con un carácter literal de línea de \nhilo.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.