2010-01-29 9 views
9

He pasado por el sed one liners pero sigo teniendo problemas con mi objetivo. Quiero sustituir las cadenas correspondientes en todas las líneas excepto en la primera aparición. Mi uso exacto sería:Tener sed hacer sustituto en la cadena, pero OMITIR primera aparición

$ echo 'cd /Users/joeuser/bump bonding/initial trials' | sed <<MAGIC HAPPENS> 
cd /Users/joeuser/bump\ bonding/initial\ trials 

La línea de reemplaza el espacio en bump bonding con el espacio barra bump\ bonding para que pueda ejecutar esta línea (ya que cuando los espacios no se escaparon yo no sería capaz de cd para eso).

actualización: He resuelto esto sólo por el uso de comillas simples y dar salida a

cd 'blah blah/thing/another space/' 

y luego usando source para ejecutar el comando. Pero no respondió mi pregunta. Todavía tengo curiosidad ... ¿cómo usarías sed para arreglarlo?

Respuesta

9

Puede evitar el problema con g y n

Reemplazar todas, deshace la primera:

Aquí hay otro método que utiliza el comando t rama-si-sustituido:

sed ':a;s/\([^ ]* .*[^\\]\) \(.*\)/\1\\ \2/;ta' 

que tiene la ventaja de dejar secuencias backslash-espaciales existentes en la entrada intacto.

+0

Su primera respuesta parece ser la solución universal. Con un poco de lectura, la bandera -e parece ser lo que realmente estaba buscando. – physicsmichael

8
s/ /\\ /2g 

El 2 especifica que el segundo debe aplicar y la g especifica que todo el resto debe aplicarse también. (Esto probablemente sólo funciona en GNU sed. De acuerdo con la Especificación Base Open Group, "If both g and n are specified, the results are unspecified.")

+0

Tiene la razón sobre el GNU sed. En mi Mac no funciona. Pero este es el tipo exacto de solución elegante que estaba buscando. – physicsmichael

+1

@physicsmichael Puede instalar GNU sed en una Mac con 'brew install gsed'. Después de la instalación, puede escribir el comando como '/ usr/local/bin/gsed' en lugar de' sed'. – stacko

1

uso awk

$ echo cd 'blah blah/thing/another space/' | awk '{for(i=2;i<NF;i++) $i=$i"\\"}1' 
cd blah\ blah/thing/another\ space/ 

$ echo 'cd /Users/joeuser/bump bonding/initial trials' | awk '{for(i=2;i<NF;i++) $i=$i"\\"}1' 
cd /Users/joeuser/bump\ bonding/initial\ trials 
Cuestiones relacionadas