shell - masivamente - ¿La mejor manera de buscar/reemplazar en varios archivos?
grepwin (4)
¿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.
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.
-re
Como dijo Paul, primero quiere encontrar los archivos que desea editar y luego editarlos. Una alternativa al uso de find es usar GNU grep (el predeterminado en Ubuntu), por ejemplo:
grep -r -l from . | xargs -0 -n 1 sed -i -e ''s/from/to/g''
También puedes usar ack-grep (sudo apt-get install ack-grep o visitar http://petdance.com/ack/ ) también, si sabes que solo quieres un cierto tipo de archivo, y quieres ignorar las cosas en directorios de control de versiones. por ejemplo, si solo quieres 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 usar perl, que puede procesar múltiples archivos por comando, por ejemplo,
grep -r -l from . | xargs perl -pi.bak -e ''s/from/to/g''
Aquí, se le dice a Perl que edite en su lugar, haciendo un archivo .bak primero.
Puede combinar cualquiera de los lados izquierdos de la tubería con los lados derechos, según sus preferencias.
Una alternativa a sed
es usar rpl
(por ejemplo, disponible en http://rpl.sourceforge.net/ o su distribución GNU / Linux), como rpl --recursive --verbose --whole-words ''F'' ''A'' grades/
Voy a agregar otro ejemplo para las personas que usan Ag
, The Silver Searcher para buscar / reemplazar operaciones en múltiples archivos.
Ejemplo completo:
ag -l "search string" | xargs sed -i '''' -e ''s/from/to/g''
Si analizamos esto, 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
Finalmente, el comando de reemplazo de cadena:
# -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''
find . -type f -print0 | xargs -0 -n 1 sed -i -e ''s/from/to/g''
La primera parte de eso es un comando de búsqueda para encontrar 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á usando svn beware. Sus directorios .svn serán buscados y reemplazados también. Tienes que excluir esos, 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''