¿Cómo encontrar y reemplazar una cadena sin usar el comando Sed?

Como todos sabemos, sed es muy eficaz para buscar y reemplazar cadenas, por ejemplo, encontrar «a» y reemplácelo por «b»: sed "s/a/b/g".

¿Es posible hacer esto con otro comando o script de shell en lugar de sed?

Esto es para sistemas Linux recortados para TV que no tienen el comando sed. Así que tengo que usar otros comandos o secuencias de comandos en lugar de sed "s/a/b/g". –

Comentarios

  • En realidad, eso es solo sustitución basada en expresiones regulares. Cualquier herramienta o lenguaje capaz de manejar tal cosa podrá hacer lo mismo, pero con varias sintaxis: $var=~s/a/b/g, gsub(/a/,"b",var), var.gsub(/a/,'b'), var.replace(/a/g,'b'), preg_replace("/a/","b",$var), regsub -all a b $var. Además de eso, muchas herramientas e idiomas también pueden reemplazar cadenas de texto sin formato. Entonces su pregunta es de alguna manera amplia.
  • ¿Por qué? ¿Qué problema está tratando de resolver?
  • Un sistema Linux recortado para TV no tiene comando sed. Así que tengo que usar otro comando o script en lugar de sed ‘ s / a / b / g ‘.

Respuesta

Sí, hay varias formas de hacer esto. También puedes usar awk, perl o bash para realizar estas actividades. En general, aunque sed es probablemente la herramienta más apropiada para realizar este tipo de tareas.

Ejemplos

Digamos que tengo estos datos de muestra, en un archivo data.txt:

foo bar 12,300.50 foo bar 2,300.50 abc xyz 1,22,300.50 

awk

$ awk "{gsub("foo", "foofoofoo", $0); print}" data.txt foofoofoo bar 12,300.50 foofoofoo bar 2,300.50 abc xyz 1,22,300.50 

Perl

$ perl -pe "s/foo/foofoofoo/g" data.txt foofoofoo bar 12,300.50 foofoofoo bar 2,300.50 abc xyz 1,22,300.50 

Edición en línea

Lo anterior Los ejemplos también pueden modificar directamente los archivos. El ejemplo de Perl es trivial. Simplemente agregue el -i modificador.

$ perl -pie "s/foo/foofoofoo/g" data.txt 

Para awk «un poco menos directo pero igual de efectivo:

$ { rm data.txt && awk "{gsub("foo", "foofoofoo", $0); print}" > data.txt; } < data.txt 

Este método crea un sub-shell con las llaves» {…} `donde está el archivo redirigido a él a través de esto:

$ { ... } < data.txt 

Una vez que el archivo ha sido redirigido al sub-shell, «se elimina y luego awk se ejecuta en el contenido del archivo que se leyó en los subconjuntos STDIN. Luego, awk procesa este contenido y se vuelve a escribir con el mismo nombre de archivo que acabamos de eliminar, reemplazándolo de manera efectiva.

Comentarios

  • Gracias por su respuesta y lo intentaré el próximo día hábil. Pero no estoy seguro si funciona porque es posible que algún comando no exista en un sistema de TV Linux recortado, como ‘ sed ‘. Así que todavía quiero usar comando ‘ busque ‘, ‘ grep ‘ y así sucesivamente para resolverlo.
  • @binghenzq – ‘ he agregado ejemplos que editan el archivo en línea.
  • -1 Rara vez voto en contra, pero en este caso el punto de la pregunta parecía ser un método más simple en lugar de otro más / igualmente complejo y probablemente también dependiente. Si la pregunta fuera solo sobre alternativas para una instalación completa de la máquina * nix, entonces probablemente haría +1 en esta buena respuesta.
  • @MichaelDurrant: acabo de agregar esas elaboradas ediciones en línea porque el OP las solicitó . Además, el OP estableció el requisito de NO usar sed no I. Sed es la herramienta apropiada para hacer sustituciones como esta, y él ‘ s obviamente está pidiendo entender mejor los roles de estas herramientas, por lo que mostrarle a alguien estas cosas, aunque malas, es extremadamente educativo para mostrarle por qué. Demasiadas veces, las personas informadas simplemente dicen » no ‘ t hacerlo » sin explicar por qué, así soy. Pero gracias por al menos dejar un comentario sobre por qué DV.
  • Claro, pensé que era una gran respuesta en todos los demás aspectos. sí, odio -1 sin explicación.

Respuesta

La alternativa clásica para sustituciones de una sola letra es tr comando que debería estar disponible en casi cualquier sistema:

$ echo "foobar" | tr a b foobbr 

tr es mejor que sed para esto en realidad ya que se usa sed (y mucho menos perl o awk) para sustituciones de una sola letra es como usar un mazo para matar una mosca.

grep no está diseñado para esto, no modifica su entrada, solo busca a través de ella.

Alternativamente, puede usar las capacidades de sustitución de algunos shells. Aquí, usando la sintaxis ksh, zsh o bash:

$ foo="foobar" $ echo "${foo//a/b}" foobbr 

Podríamos darle respuestas más específicas si explicara exactamente qué problema está tratando de resolver.

Comentarios

  • ¿Existe una opción para ignorar las mayúsculas y minúsculas en ${foo//a/b}?
  • @ AlikElzin-kilaka ‘ tengo miedo no. ‘ tendrás que usar algo más sofisticado como, por ejemplo: echo "$foo" | sed 's/a/b/i o dar una clase de carácter: echo ${foo//[aA]/b}.

Respuesta

Puede utilizar la herramienta POSIX ex:

ex a.txt <<eof %s/Sunday/Monday/g xit eof 

https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html

Comentarios

  • muchas gracias. solo para agregar, el indicador -c es ejecutar el comando cuando comienza la edición (ya que ex es un editor) y el indicador -s es el modo de script que desactiva la retroalimentación o, como algunos les gusta decir, modo slient. ref para más información: ex-vi.sourceforge.net/ex.html

Respuesta

Si está trabajando con un archivo en lugar de una transmisión, puede usar el editor de texto estándar, ed:

printf "%s\n" ",s/a/b/g" w q | ed file.txt 

Esto debería estar disponible en cualquier * nix. La coma en ",s/a/b/g" indica ed para trabajar en cada línea (también puedes usar %, que te resultará más familiar si estás acostumbrado a vim) y el resto de él es una búsqueda y reemplazo estándar. w le dice que escriba (guarde) el archivo, q le dice que salga.

Tenga en cuenta que, a diferencia de sed «s -i opción (y opciones similares en otras herramientas), esto en realidad edita el archivo en el lugar en lugar de hacer trampa con archivos temporales.

No «No creo que sea posible hacer que esto funcione con transmisiones, pero realmente no sé mucho acerca de ed y no me sorprendería si realmente tuviera esa capacidad (la filosofía de Unix es lo que es).

Respuesta

Usando el ancestro (en el que -s significa silencioso (silencioso) y la coma antes de los comandos significa ejecutar en todas las líneas):

Solo imprimiendo en STDOUT :

ed -s file <<! ,s/a/b/g ,p q ! 

reemplazando en el lugar:

ed -s file <<! ,s/a/b/g w q ! 

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *