2009-02-09 18 views
33

¿cuál es la mejor manera de hacer esto? No soy un guerrero de línea de comando, pero estaba pensando que posiblemente hay una forma de usar grep y cat.¿La mejor manera de buscar/reemplazar en varios archivos?

solo quiero reemplazar una cadena que ocurre en una carpeta y subcarpetas. ¿Cuál es la mejor manera de hacer esto? Estoy ejecutando ubuntu si eso importa.

-d

+0

Acabo de dejar este enlace aquí: http://stackoverflow.com/questions/102083/whats-the-best-tool-to-find-and-replace-regular-expressions-over-multiple-files –

Respuesta

36
find . -type f -print0 | xargs -0 -n 1 sed -i -e 's/from/to/g' 

La primera parte de que es una orden de búsqueda para buscar los archivos que desea cambiar. Es posible que deba modificarlo adecuadamente. El comando "xargs" toma cada archivo encontrado y lo aplica al comando "sed". El comando "sed" toma cada instancia de "desde" y la reemplaza por "a". Esa es una expresión regular estándar, así que modifícala como lo necesites.

Si está utilizando svn tenga cuidado. Sus directorios .svn serán buscados y reemplazados también. Usted tiene que excluir a las personas, por ejemplo, así:

find . ! -regex ".*[/]\.svn[/]?.*" -type f -print0 | xargs -0 -n 1 sed -i -e 's/from/to/g'

o

find . -name .svn -prune -o -type f -print0 | xargs -0 -n 1 sed -i -e 's/from/to/g'

+0

no parece que este comando esté recurriendo a subdirectorios. ¿Hay algo que estoy haciendo mal? – blackrobot

+0

¿Qué te hace pensar que no está recurriendo a los directorios? –

+0

los archivos de texto en los subdirectorios no hacen los cambios. lo que quiero que haga es esto: cambiar ocurrencias de alguna dirección .ip a somewebsite.com en todos los subdires. – blackrobot

37

Como dijo Pablo, que desea encontrar primero los archivos que desea editar y luego editarlos. Una alternativa al uso hallazgo es utilizar grep de GNU (el valor por defecto en Ubuntu), por ejemplo:

grep -r -l from . | xargs -0 -n 1 sed -i -e 's/from/to/g' 

También puede utilizar ACK-grep (sudo apt-get install ACK-grep o visite http://petdance.com/ack/), así, si usted sabe que solo quiere un cierto tipo de archivo y desea ignorar las cosas en los directorios de control de versiones. por ejemplo, si sólo desea que los archivos de texto,

ack -l --print0 --text from | xargs -0 -n 1 sed -i -e 's/from/to/g' 
# `from` here is an arbitrary commonly occurring keyword 

una alternativa al uso de sed es el uso de Perl que pueden procesar varios archivos al comando, por ejemplo,

grep -r -l from . | xargs perl -pi.bak -e 's/from/to/g' 

Aquí, Perl se le dice a editar en colocar, haciendo un archivo .bak primero.

Puede combinar cualquiera de los lados izquierdos de la tubería con los lados derechos, según sus preferencias.

+0

Puede evitar directorios de control de versiones en "buscar" usando el comando "-prune". Por ejemplo, "find. -name RCS -prune -o -type f -print0" –

+0

Es cierto, aunque requiere menos capacidad intelectual para que una herramienta como ack lo maneje por usted. –

+0

ack también acepta una opción '--print0' para usar null como un delimitador entre los nombres de los archivos, por lo que su comando ack se vería así:' ack -l --print0 --text from | xargs -0 -n 1 sed -i -e 's/from/to/g'' –

3

Una alternativa a sed está utilizando rpl (por ejemplo disponible de http://rpl.sourceforge.net/ o su distribución de GNU/Linux), como rpl --recursive --verbose --whole-words 'F' 'A' grades/

14

voy a tirar en otro ejemplo para la gente utilizando Ag, The Silver Searcher hacer buscar/reemplazar las operaciones en varios archivos .

Ejemplo completo:

ag -l "search string" | xargs sed -i '' -e 's/from/to/g' 

Si rompemos este hacia abajo, lo que obtenemos es:

# returns a list of files containing matching string 
ag -l "search string" 

A continuación, tenemos:

# consume the list of piped files and prepare to run foregoing command 
# for each file delimited by newline 
xargs 

Por último, el comando de sustitución de cadenas :

# -i '' means edit files in place and the '' means do not create a backup 
# -e 's/from/to/g' specifies the command to run, in this case, 
# global, search and replace 

sed -i '' -e 's/from/to/g' 
Cuestiones relacionadas