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
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 ed (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 !
$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.