usando sed con ampersand (&)

19

Estoy usando sed para buscar y reemplazar patrones dentro de los archivos SAS que tengo en lugar de cambiarlos individualmente. El problema es que estoy tratando de reemplazar variables macro y cuando uso los ampers y no se procesa correctamente.

Here's my code:
sed -ie 's/user=&uid./user=&sysuserid./g' *_table_*.sas

cada vez que ejecuto este comando parece agregar y hacer todo tipo de cosas funky con el texto original.

Pregunta: ¿Cómo reemplazo el texto que contiene símbolos con comando sed?

lucasdavis500
fuente
66
&es un personaje especial, por lo que debe escaparse cuando se usa en el RHS; en su caso, debe correr, 's/user=&uid./user=\&sysuserid./g'aunque sospecho que también necesita escapar del punto en el LHS para que coincida con un punto literal, por lo que realmente necesita's/user=&uid\./user=\&sysuserid./g'
don_crissti
1
sí, '&' a la derecha básicamente significa "todo lo que coincide a la izquierda", así que escapa con '\'. Debes hacer que esa sea la respuesta, en lugar de solo un comentario.
Edward Falk
no tuve que escapar el primer período ... solo un
aviso

Respuestas:

25

&es especial en el texto de reemplazo: significa “toda la parte de la entrada que se corresponde con el patrón”, así que lo que estás haciendo aquí reemplaza user=&uidXcon user=user=&uidXsysuserid.. Para insertar un ampersand real en el texto de reemplazo, use \&.

Otra cosa que parece incorrecta es que .en el patrón de búsqueda se encuentra cualquier carácter (excepto una nueva línea), pero .al final del texto de reemplazo hay un punto literal. Si desea reemplazar solo la cadena literal user=&uid., protéjala .con una barra diagonal inversa.

sed -e 's/user=&uid\./user=\&sysuserid./g'

Si desea reemplazar cualquier carácter y preservarlo en el resultado, coloque el carácter en un grupo y úselo \1en el reemplazo para referirse a ese grupo.

sed -e 's/user=&uid\(.\)/user=\&sysuserid\1/g'

De hecho, dada la repetición entre el texto original y el reemplazo, debería usar grupos de todos modos:

sed -e 's/\(user=&\)u\(id\.\)/\1sysuser\2/g'

es decir, "reemplazar upor sysuserentre user=&y id.".

Gilles 'SO- deja de ser malvado'
fuente
podrías explicar grupos?
lucasdavis500
2
@ lucasdavis500 Un grupo identifica una parte del patrón. Está delimitado por una barra invertida entre paréntesis. Por ejemplo, \(user=&\)es un patrón que coincide user&y almacena la cadena de coincidencia como un grupo (grupo número 1 ya que es el primer grupo en el patrón). Luego, en el reemplazo \1se reemplaza por la cadena almacenada para el grupo número 1.
Gilles 'SO- deja de ser malvado'
¿te refieres a (user = &) almacena user = &, no user &?
lucasdavis500
@ lucasdavis500 No entiendo tu comentario. El carácter =en las expresiones regulares y en el texto de reemplazo se representa a sí mismo, por lo que user=&solo coincide user=&, y user=&en el texto de reemplazo se obtiene user=la parte de la línea que coincide con la expresión regular.
Gilles 'SO- deja de ser malvado'
1
@ lucasdavis500 El =personaje no tiene ningún significado especial. user=&en el texto de reemplazo produce user=seguido por el texto original coincidente. user=\&en el texto de reemplazo produceuser=&
Gilles 'SO- deja de ser malvado'