¿Te refieres a buscar y reemplazar una cadena en todos los archivos que coincidan con grep?
perl -p -i -e 's/oldstring/newstring/g' `grep -ril searchpattern *`
Editar
Dado que esta parece ser una pregunta bastante popular, pensé que actualizaría.
Hoy en día lo uso principalmente ack-grep
porque es más fácil de usar. Entonces el comando anterior sería:
perl -p -i -e 's/old/new/g' `ack -l searchpattern`
Para manejar los espacios en blanco en los nombres de los archivos, puede ejecutar:
ack --print0 -l searchpattern | xargs -0 perl -p -i -e 's/old/new/g'
puedes hacer más con ack-grep
. Supongamos que desea restringir la búsqueda solo a archivos HTML:
ack --print0 --html -l searchpattern | xargs -0 perl -p -i -e 's/old/new/g'
Y si el espacio en blanco no es un problema, es aún más corto:
perl -p -i -e 's/old/new/g' `ack -l --html searchpattern`
perl -p -i -e 's/old/new/g' `ack -f --html`
Can't open Untitled: No such file or directory, <> line 5
al intentar "Carpeta sin título / archivo.txt".Esto parece ser lo que desea, según el ejemplo que dio:
sed -i 's/foo/bar/g' *
No es recursivo (no descenderá a subdirectorios). Para una buena solución reemplazando archivos seleccionados a lo largo de un árbol, usaría find:
find . -name '*.html' -print -exec sed -i.bak 's/foo/bar/g' {} \;
La
*.html
es la expresión que los archivos deben coincidir,.bak
después de que-i
hace una copia del archivo original, con una extensión .bak (puede ser cualquier extensión que desee) yg
al final de la expresión sed le dice a sed que reemplace múltiples copias en una línea (en lugar de solo la primera). La función-print
de buscar es una conveniencia para mostrar qué archivos se estaban haciendo coincidir. Todo esto depende de las versiones exactas de estas herramientas en su sistema.fuente
find
comando un directorio desde el que comenzar, por ejemplofind . -name '*.html'
ofind directoryname/ -name '*'
.sed -ie 's/foo/bar/g' *
Si
sed(1)
tiene una-i
opción, úsela así:for i in *; do sed -i 's/foo/bar/' $i done
Si no es así, hay varias formas de variaciones en lo siguiente según el idioma con el que quieras jugar:
ruby -i.bak -pe 'sub(%r{foo}, 'bar')' * perl -pi.bak -e 's/foo/bar/' *
fuente
for i in *; do ...
es redundante, sed puede tomar una lista de archivos como argumentos.for i in *; do; sed -i 's/foo/bar/g' "$i"; done
Me gusta y utilicé la solución anterior o una búsqueda y reemplazo en todo el sistema entre miles de archivos:
find -name '*.htm?' -print -exec sed -i.bak 's/foo/bar/g' {} \;
Supongo que con el '* .htm?' en lugar de .html, busca y encuentra archivos .htm y .html por igual.
Reemplazo el .bak con la tilde (~) más utilizada en el sistema para facilitar la limpieza de los archivos de respaldo.
fuente
Esto funciona usando grep sin necesidad de usar perl o find.
grep -rli 'old-word' * | xargs -i@ sed -i 's/old-word/new-word/g' @
fuente
-i
que no funcionaba para otros sistemas operativos. Funciona para mí en ubuntu.xargs
manual (en Ubuntu) dice que-i
está en desuso y que se debe usar-I
en su lugar. Entonces, deberíamos decir:grep -rli 'old-word' * | xargs -I filepath sed -i 's/old-word/new-word/g' filepath
find . -type f -print0 | xargs -0 <sed/perl/ruby cmd>
procesará múltiples nombres de archivos contenidos en el espacio a la vez, cargando un intérprete por lote. Mucho mas rápido.fuente
La respuesta ya dada de usar find y sed
find -name '*.html' -print -exec sed -i.bak 's/foo/bar/g' {} \;
es probablemente la respuesta estándar. O puede usar en
perl -pi -e s/foo/bar/g'
lugar delsed
comando.Para los usos más rápidos, puede encontrar que el comando rpl es más fácil de recordar. Aquí está el reemplazo (foo -> bar), recursivamente en todos los archivos en el directorio actual:
rpl -R foo bar .
No está disponible de forma predeterminada en la mayoría de las distribuciones de Linux, pero se instala rápidamente (
apt-get install rpl
o similar).Sin embargo, para trabajos más difíciles que involucran expresiones regulares y sustitución hacia atrás, o cambios de nombre de archivos, así como buscar y reemplazar, la herramienta más general y poderosa que conozco es repren , un pequeño script de Python que escribí hace un tiempo para algunos tareas de refactorización y cambio de nombre más complicadas. Las razones por las que podría preferirlo son:
Consulte el archivo README para ver ejemplos.
fuente
En realidad, esto es más fácil de lo que parece.
grep -Rl 'foo' ./ | xargs -n 1 -I % sh -c "ls %; sed -i 's/foo/bar/g' %";
Pan comido. Si comprende bien find, grep, xargs, sed y awk, casi nada es imposible cuando se trata de la manipulación de archivos de texto en bash :)
fuente