¿Cómo buscar y reemplazar múltiples agujas por una palabra a través de una expresión?

8

Suponga que tiene un archivo de texto:

foo fnord bar
bizz foo poit

Y ahora me gustaría reemplazar "foo" y "bar" en "narf".

Sé que podría usar:

 sed -e 's/foo/narf/g' -e 's/bar/narf/g' fileName

Sin embargo, me gustaría trabajar con un operador OR que le dice a la expresión regular que coincida con ambas agujas a través de una expresión.

Supongo que algunos manuales deberían ajustarse a mis necesidades, pero intenté

sed -e 's/foo|bar/narf/g' -i fileName

y no funcionó y ni siquiera arroja un error.

¿Qué estoy haciendo mal aquí?

k0pernikus
fuente

Respuestas:

10

Use la -ropción para la sintaxis de expresiones regulares extendidas:

sed -r -e 's/foo|bar/narf/g'

De lo contrario, escape de la disyunción como \|:

sed -e 's/foo\|bar/narf/g'
Stéphane Gimenez
fuente
6

Existen muchas variaciones en la sintaxis de expresiones regulares . Las primeras herramientas en el mundo de Unix que tenían expresiones regulares no tenían las capacidades completas de las expresiones regulares, solo conjuntos de caracteres ( […]y .), repetición ( *) y anclas de línea ( ^y $). Las expresiones regulares básicas solo tienen estos operadores. Sed es una herramienta de la vieja escuela y utiliza expresiones regulares básicas.

Muchas implementaciones sed tienen extensiones para la coincidencia completa de expresiones regulares. Debido a que el personaje se |representa a sí mismo, debe usarlo \|para alternar, y de manera similar \(y \)para agrupar. Tenga en cuenta que el estándar POSIX no exige que \|sea ​​compatible con las expresiones regulares básicas , y algunos sistemas (por ejemplo, OpenBSD ) no lo tienen.

Algunas versiones de sed tienen una opción para cambiar a expresiones regulares extendidas , donde (…)se usa para agrupar y |alternar. Con GNU sed (es decir, bajo Linux o Cygwin) o Busybox , pasa la -ropción. En FreeBSD u OSX , pase la -Eopción.

Si su sed no tiene alternancia, puede llamar en su awklugar. POSIX lo exige , pero es un poco detallado para esta tarea, y no admite referencias posteriores.

awk '{gsub(/foo|bar/, "narf")}' <fileName.old >fileName.new

Por cierto, solo GNU y Busybox sed admiten el reemplazo de archivos en su lugar. Awk y otras versiones de sed no. Consulte ¿Puedo hacer que 'cortar' cambie un archivo en su lugar?

Si tiene Perl, a menudo es útil en una forma de herramienta única para todo tipo de procesamiento de texto. La mayoría de lo que es fácil en sed, awk y el resto no es mucho más difícil en Perl, y puedes aprender una sola herramienta (si es compleja).

perl -i -pe 's/foo|bar/narf/g' fileName
Gilles 'SO- deja de ser malvado'
fuente
0

Puede usar Vim en modo Ex:

ex -sc '%s/\vPA|QU/RO/g|x' file
  1. % seleccione todas las líneas

  2. s sustituir

  3. \v encender la magia

  4. g reemplazo global

  5. x guardar y cerrar

Steven Penny
fuente