Sed: ¿reemplazar un personaje en una línea coincidente en su lugar?

21

En un archivo que contiene líneas como esta:

# lorem ipsum blah variable

Me gustaría eliminar el carácter #(comentario) en la misma línea que contiene una cadena específica, en su lugar. ¿Es sedbueno para esto?

Estoy luchando para que este condicional funcione. Tengo una forma "torpe" de hacer esto; Puedo encontrar el número de línea coincidente con awko sedy luego usar este número en un sedcomando separado , pero creo que esto se puede hacer de una manera mucho mejor.

Kamil
fuente

Respuestas:

36

Use la cadena que está buscando como selector de las líneas que se utilizarán:

sed '/ipsum/s/#//g'

/ipsum/selecciona líneas que contienen "ipsum" y solo en estas líneas se ejecutan los comandos que siguen. Puedes usar llaves para ejecutar más comandos

/ipsum/{s/#//g;s/@/-at-/g;}
peterph
fuente
44
Estoy de acuerdo; Esta es la mejor respuesta (aunque no la única). Comentarios: (1) 's/#//g'eliminará todos los #caracteres en la línea. Si eso no es lo que desea, elimine el g(que significa "global"). (2) Para editar un archivo en su lugar (como se solicitó en la pregunta), use sed -i.
G-Man dice 'reinstalar a Monica' el
2
(3) Como una cuestión de situaciones del mundo real, si desea descomentar una línea, es posible que desee usar sed -i '/ipsum/s/#[[:space:]]*//', para deshacerse de los espacios y pestañas inmediatamente después de la #. (4) También es posible que desee considerar verificar que #sea ​​el primer carácter no en blanco de la línea. El comando actual eliminaría el #de la línea prompt "Enter # of ipsums:".
G-Man dice 'reinstalar a Monica' el
1
@ G-Man - ¡gran adición! Para su segundo pt (espacio inicial), ¿qué pasa con: sed -i '/ipsum/s/^#[[:space:]]*//'?! ( ^significa inicio de línea, $para final de línea) - al menos en gnu sed ...
Jeremy Davis
1
@JeremyDavis: Sí, podrías anclar la expresión regular al comienzo de la línea con ^, pero eso estaría mal. A menudo comento el código sangrado colocando el #inmediatamente antes del código, por lo que #está sangrado. Dudo que sea la única persona que hace eso.
G-Man dice 'reinstalar a Monica' el
1
@ G-Man: ¡ah, por supuesto! Gracias, no lo había considerado. Por lo que también querría para comprobar si hay espacios en blanco entre ^Y #, por lo que algo de la misma familia: /ipsum/{/^[[:space:]]*#/s/#[[:space:]]*//}. Aunque incluso entonces, dependiendo de dónde #esté, aún puede causar problemas (por ejemplo, en idiomas que usan sangría / separación de espacios en blanco).
Jeremy Davis
7
$ cat input.txt
# lorem ipsum blah variable
# lorem ipsum blat variable
# lorem ipsum blow variable
# lorem ipsum blip variable
# lorem ipsum blue variable

luego:

$ sed 's|# \(.*blue.*\)|\1|' input.txt

da:

# lorem ipsum blah variable
# lorem ipsum blat variable
# lorem ipsum blow variable
# lorem ipsum blip variable
lorem ipsum blue variable

Funciona de la siguiente manera:

El sle dice sedque debe sustituir lo que encuentra la expresión regular.

El patrón es el # \(.*blue.*\)que se descompone en: Encuentra un hash seguido de un espacio. El corchete ( \() comienza la agrupación. .*blue.*Es la palabra bluecon cualquier cosa antes y después. El siguiente paréntesis ( \)) cierra la agrupación.

El reemplazo es el \1que es una referencia al contenido del primer grupo de agrupación.

garethTheRed
fuente
3

Puede usar Vim en modo Ex:

ex -sc '/ipsum/s/#//|x' file
  1. s sustituir

  2. x guardar y cerrar

Steven Penny
fuente
Eso es muy bonito. ¡No sabía sobre eso! TBH, no estoy seguro de que sea la mejor respuesta para esta pregunta (en mi opinión, la respuesta principal es la correcta), ¡pero sigue siendo genial! Gracias por publicar.
Jeremy Davis