2011-09-10 18 views
13

que tengo un archivo que tiene el siguiente aspecto:usando sed para copiar líneas y eliminar caracteres de los duplicados

@"Afghanistan.png", 
@"Albania.png", 
@"Algeria.png", 
@"American_Samoa.png", 

quiero que se vea como este

@"Afghanistan.png", 
@"Afghanistan", 
@"Albania.png", 
@"Albania", 
@"Algeria.png", 
@"Algeria", 
@"American_Samoa.png", 
@"American_Samoa", 

pensé que podía usar sed para hacer esto pero no puedo descifrar cómo almacenar algo en un buffer y luego modificarlo.

¿Incluso utilizo la herramienta adecuada?

Gracias

Respuesta

11

que es bastante fácil de hacer con sed y que ni siquiera tienen que utilizar el espacio de bodega (la memoria intermedia auxiliar sed). Dado el archivo de input a continuación:

$ cat input 
@"Afghanistan.png", 
@"Albania.png", 
@"Algeria.png", 
@"American_Samoa.png", 

se debe utilizar este comando:

sed 's/@"\([^.]*\)\.png",/&\ 
@"\1",/' input 

El resultado:

$ sed 's/@"\([^.]*\)\.png",/&\ 
@"\1",/' input 
@"Afghanistan.png", 
@"Afghanistan", 
@"Albania.png", 
@"Albania", 
@"Algeria.png", 
@"Algeria", 
@"American_Samoa.png", 
@"American_Samoa", 

Este comando es simplemente un comando de reemplazo (s///). Coincide con cualquier cosa que comience con @" seguido por caracteres que no sean de punto ([^.]*) y luego por .png",. Además, coincide con todos los caracteres que no sean de punto antes de .png", utilizando los corchetes de grupo \( y \), por lo que podemos obtener lo que coincide con este grupo. Por lo tanto, esta es la expresión regular que debe sustituirse:

@"\([^.]*\)\.png", 

Sigue la parte de reemplazo del comando. El comando & simplemente inserta todo lo que coincide con @"\([^.]*\)\.png", en el contenido modificado. Si fuera el único elemento de la pieza de reemplazo, no se cambiaría nada en la salida. Sin embargo, después del & hay un carácter de línea nueva representado por la barra invertida \ seguida de una nueva línea real, y en la línea nueva agregamos la cadena @" seguida del contenido del primer grupo (\1) y luego la cadena ",.

Esto es solo una breve explicación del comando. Espero que esto ayude. Además, tenga en cuenta que puede usar la cadena \n para representar nuevas líneas en algunas versiones de sed (como GNU sed). Se haría un comando más concisa y fácil de leer:

sed 's/@"\([^.]*\)\.png",/&\[email protected]"\1",/' input 
+0

excepcional. No le importaría explicar su línea de comando fu, ¿verdad? –

+0

Solo intentaba explicarlo incluso antes de leer su comentario :) Espero que aclare la solución. Sería un placer responder cualquier pregunta restante al respecto. – brandizzi

14

Usted no tiene que ser complicado con expresiones regulares y cadenas de repuesto: Use p comando de sed que muestre la línea intacta, a continuación, modificar la línea y dejar que la impresión implícita la respuesta de

sed 'p; s/\.png//' 
10

Glenn Jackman está bien, pero también duplica las filas que no coinciden con la expresión.

Ésta, en cambio, se duplica sólo las filas que han concordado con la expresión:

sed -n 'p; s/\.png//p' 

Aquí, -n es sinónimo de "imprimir nada menos que explícitamente impresa", y el p en s/\.png//p fuerza la impresión si la sustitución fue hecho, pero no obliga a que de lo contrario

8

prefiero este sobre Carles Sala y Glenn Jackman:

sed '/.png/p;s/.png//' 

sólo podría decir que es p personales referencia.

0

o se puede combinar las dos versiones y aplicar la duplicación sólo en las líneas que coincidan el patrón requerido

sed -e '/^@".*\.png",/{p;s/\.png//;}' input 
Cuestiones relacionadas