2012-04-25 25 views
21

Estoy teniendo problemas para averiguar cómo utilizar sed para buscar y reemplazar cadenas que contengan el carácter / en un archivo de texto /etc/myconfig.búsqueda de sed y las cuerdas que contiene reemplazar/

Por ejemplo, en mi archivo de texto existente, que tengo:

myparam /path/to/a argB=/path/to/B xo 

y quiero que esto sustituye por:

myparam /path/to/c argB=/path/to/D xo 

intenté hacer esto en bash:

line='myparam /path/to/a argB=/path/to/B xo' 
line_new='myparam /path/to/c argB=/path/to/D xo' 
sed -i 's/$line/$line_new/g' /etc/myconfig 

Pero no pasa nada.

Intentando

grep -rn "$line" /etc/myconfig 

me hace volver 'myparam /path/to/a argB=/path/to/B xo' sin embargo.

¿Cuál es la forma correcta de expresar mi comando sed para ejecutar esta búsqueda y reemplazar y manejar correctamente el comando /? (Creo que el personaje / en mis cadenas son las que me está dando el problema, ya que se utiliza un comando similar sed para buscar y reemplazar otra línea en el archivo de texto sin problemas y que la línea no tiene un carácter /.

+1

Las reglas de sustitución y cita son realmente sobre bash en lugar de sed específicamente. Es posible que desee agregar bash como una etiqueta. – KarlM

+0

bien. agregará 'bash' como una etiqueta. –

Respuesta

32

no escapar de las barras invertidas; podrás confundes Utilice un símbolo diferente después del comando s que no aparece en el texto (estoy usando % en el ejemplo siguiente):

line_old='myparam /path/to/a argB=/path/to/B xo' 
line_new='myparam /path/to/c argB=/path/to/D xo' 
sed -i "s%$line_old%$line_new%g" /etc/myconfig 

también. , encierre toda la cadena entre comillas dobles, usando comillas simples significa que sed ve $line (en el original) en lugar del valor expandido. Dentro de comillas simples, no hay expansión y no hay metacaracteres. Si su texto puede contener casi cualquier carácter de texto sin formato, use un carácter de control (por ejemplo, control-A o control-G) como delimitador.

Tenga en cuenta que el uso de -i aquí refleja lo que está en la pregunta, pero que asume el uso de GNU sed. BSD sed (que se encuentra en Mac OS X también) requiere un sufijo. Puede usar sed -i '' … para reemplazar in situ; eso no funciona con GNU sed. Para ser portátil entre los dos, use -i.bak; eso funcionará con ambos, pero le da un archivo de copia de seguridad que probablemente quiera eliminar. Otras plataformas Unix (por ejemplo, AIX, HP-UX, Solaris) pueden tener variantes de sed que no son compatibles con -i en absoluto. No es requerido por la especificación POSIX para sed.

+0

gracias!La comilla doble '" 'y'% 'hicieron el truco. Intenté originalmente escapar del caracter'/'haciendo' \/'y eso no funcionó en absoluto. –

+0

Tenga en cuenta que si necesita especificar un rango de líneas por regex y la expresión regular contiene barras, puede usar 'sed -n '\ @ dir/file @, \ @ dir2/file2 @ p' donde la barra invertida antes de' '' indica que '@' es el delimitador de búsqueda para esta expresión. –

+0

Tenga en cuenta que uno puede necesitar 'sed -i -e' – PhysicalChemist

12

Esto podría funcionar para usted:

sed -i "s|$line|$line_new|g" /etc/myconfig 

debe utilizar " 's para que el $line y $new_line se interpolan. También use | o cualquier carácter no encontrado en el partido o cadenas de reemplazo como un delimitador.

+1

bien. No sabía sobre el truco '|'. ¿Quiere decir que CUALQUIER delimitador funcionará siempre que no se encuentre un carácter en las cadenas de búsqueda o reemplazo? –

+0

Sí; el primer caracter después de 's' se usa para separar el comando en dos partes; el patrón a igualar y el patrón de reemplazo. 's/search/replace /' usa '/' tres veces; pero 's | search | replace |' o 's% search% replace%' funciona también. Perl permite paréntesis coincidentes ('s {búsqueda} {reemplazar}') pero 'sed' no (a menos que, tal vez, hayas activado la opción de patrones de Perl si tienes' sed' de GNU). –

+1

Sí, dentro de lo razonable. '|' es útil para usar, ya que no es probable que aparezca en un archivo. Sin embargo, es un metacaracter (usado en alternancia) así que si quieres decir 's/this \ | that/those /' entonces usa otro delimitador como '@' o '#' o ',' o '?' O ' % 'etc. También tenga en cuenta que esto es para el comando de sustitución para el comando de búsqueda' /.../ 'para usar un delimitador alternativo precedido de la alternativa con una barra invertida, por ejemplo '\ | foo |' – potong

Cuestiones relacionadas