Consejo: No haga lo siguiente en un árbol de pago de svn ... sobrescribirá los archivos de la carpeta mágica .svn.
J. Polfer
77
Dios mío, esto es exactamente lo que acabo de hacer. Pero funcionó y no parece haber hecho ningún daño. ¿Que es lo peor que puede pasar?
J. Katzwinkel
55
@ J.Katzwinkel: al menos, puede corromper las sumas de verificación, lo que puede corromper su repositorio.
ninjagecko
3
Consejo rápido para todas las personas que usan sed: agregará nuevas líneas finales a sus archivos. Si no los quiere, primero haga un find-replace que no coincida con nada, y comprométalo a git. Entonces haz el verdadero. Luego, vuelva a crear una base interactiva y elimine el primero.
funroll
55
Puede excluir un directorio, como git, a partir de los resultados mediante el uso -path ./.git -prune -ode find . -path ./.git -prune -o -type f -name '*matchThisText*' -print0antes del conexionado a xargs
devinbost
Respuestas:
851
find /home/www \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g'
-print0le dice findque imprima cada uno de los resultados separados por un carácter nulo, en lugar de una nueva línea. En el caso improbable de que su directorio tenga archivos con nuevas líneas en los nombres, esto todavía permite xargstrabajar con los nombres de archivo correctos.
\( -type d -name .git -prune \)es una expresión que omite completamente todos los directorios nombrados .git. Puede expandirlo fácilmente, si usa SVN o tiene otras carpetas que desea preservar, solo haga coincidir con más nombres. Es más o menos equivalente a -not -path .git, pero más eficiente, porque en lugar de verificar cada archivo en el directorio, lo omite por completo. El -oafter se requiere debido a cómo -prunefunciona realmente.
En OSX puede encontrar sed: 1: "...": invalid command code .problemas. Parece que la opción -i espera una extensión y analiza el 's/../...'comando. Solución: pase la extensión '' a la opción -i como sed -i '' 's/....
Robert Lujo
66
Nota: si usa esto sobre un directorio y se pregunta por qué svn stno muestra cambios, ¡es porque también ha modificado los archivos en los directorios .svn! Usar en su find . -maxdepth 1 -type f -print0 | xargs -0 sed -i 's/toreplace/replaced/g'lugar.
ACK_stoverflow
57
Además, tenga cuidado si está en un repositorio git. Pensé que era inteligente al probar esto en una rama clara para poder revertir si hacía algo malo, pero en cambio corrompió mi índice git.
Ciryon
13
Use esto grep -r 'hello' -l --null . | xargs -0 sed -i 's#hello#world#g'para evitar editar archivos no relacionados (sed podría cambiar la codificación del archivo).
caiguanhao
66
"pero en su lugar corrompió mi índice git". No se preocupe demasiado por esto, solo puede hacer find .git ... | ... 'sed -i s/(the opposite from before)/g'para corregir su índice git
Massey101
259
Nota : No ejecute este comando en una carpeta que incluya un repositorio git; los cambios en .git podrían dañar su índice git.
find /home/www/-type f -exec \
sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g'{}+
En comparación con otras respuestas aquí, esto es más simple que la mayoría y usa sed en lugar de perl, que es lo que preguntó la pregunta original.
Tenga en cuenta que si está utilizando BSD sed (incluso en Mac OS X) deberá proporcionar una arg de cadena vacía explícita a la -iopción de sed . es decir: sed -i '' 's/original/replacement/g'
Nathan Craike el
2
@JohnZwinck Mi error, perdí el +. Aunque parezca extraño, la solución de Nikita es más rápida para mí.
Sam
66
@AoeAoe: +Reduce en gran medida el número de sedprocesos generados. Es mas eficiente.
John Zwinck
44
¿Cómo puedo hacer esto de manera segura en una carpeta con un repositorio git?
Hatshepsut
20
Es seguro para ejecutar en una carpeta que contiene un repositorio git si se excluye la cesión temporal de los resultados de la Categoría: find . -not -path '*/\.git*' -type f ....
Dale Anderson
213
La forma más simple para mí es
grep -rl oldtext .| xargs sed -i 's/oldtext/newtext/g'
@Anatoly: solo una pregunta: ¿cómo puedo excluir archivos binarios (archivos ejecutables) ?
user2284570
3
@ user2284570 Utilice los indicadores -Io --binary-file=without-matchgrep.
Zéychin
34
Esto funciona especialmente bien, cuando necesita excluir directorios, como con .svn. Por ejemplo:grep -rl oldtext . --exclude-dir=.svn | xargs sed -i 's/oldtext/newtext/g'
phyatt
11
brew install gnu-sedy usar gseden OSX para evitar un mundo de dolor.
P i
1
chicos por favor atención, si su proyecto es git versionado, use en su lugar: git grep -rl oldtext . | xargs sed -i 's/oldtext/newtext/g'. no es nada agradable joder tu .gitdirectorio
Paolo
61
Todos los trucos son casi iguales, pero me gusta este:
find <mydir>-type f -exec sed -i 's/<string1>/<string2>/g'{}+
find <mydir>: busca en el directorio.
-type f:
El archivo es de tipo: archivo normal
-exec command {} +:
Esta variante de la acción -exec ejecuta el comando especificado en los archivos seleccionados, pero la línea de comando se crea agregando cada nombre de archivo seleccionado al final; El número total de invocaciones del comando será mucho menor que el número de archivos coincidentes. La línea de comando se construye de la misma manera que xargs construye sus líneas de comando. Solo se permite una instancia de `{} 'dentro del comando. El comando se ejecuta en el directorio de inicio.
@ I159 ¿No es esta respuesta idéntica a la de John Zwinck ?
Vuelva a instalar Monica Please
1
@ user2284570 El concepto de un "archivo binario" no está completamente bien definido. Puede usar el filecomando para intentar determinar el tipo de cada archivo, pero las variaciones accidentales en su salida pueden ser un poco desconcertantes. La opción -I(aka --mime) ayuda un poco, o --mime-typesi la tiene. Lamentablemente, cómo refactorizar esta simple línea para hacer esto está lamentablemente fuera del alcance de este pequeño cuadro de comentarios. Tal vez publicar una pregunta por separado si necesita ayuda? (Tal vez agregue un comentario con un enlace aquí.)
tripleee
1
La respuesta más limpia! gracias compañero
jukerok
39
cd /home/www && find .-type f -print0 |
xargs -0 perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g'
Tengo curiosidad, ¿hay alguna razón para usar -print0y en xargslugar de -execo -execdir?
Philipp
44
Hay: de "man find": el comando especificado se ejecuta una vez para cada archivo coincidente. Es decir, si hay 2000 archivos en / home / www, entonces 'find ... -exec ...' generará 2000 invocaciones de perl; mientras que 'encontrar ... | xargs ... 'solo invocará perl una o dos veces (suponiendo ARG_MAX de aproximadamente 32K y una longitud promedio de nombre de archivo de 20).
Empleado ruso
2
@ Ruso empleado: es por eso que usarías: find -exec command {} +evita invocaciones excesivas del comando como xargs, pero sin el proceso por separado.
John Zwinck
2
¿En qué plataforma? La solución xargs es portátil, las invocaciones "mágicas" de "find ... -exec" que no invocan un subproceso por cada archivo encontrado no lo son.
Empleado ruso
44
@EmployedRussian, find -exec ... {} +se ha especificado en POSIX desde 2006.
sed -i ''-e 's/subdomainA/subdomainB/g' $(find /home/www/-type f)
NOTA : -i ''resuelve el problema de OSXsed: 1: "...": invalid command code .
NOTA : Si hay demasiados archivos para procesar, obtendrá Argument list too long. La solución alternativa: uso find -execo xargssolución descrita anteriormente.
El workarounddebe ser la sintaxis preferida en todos los casos.
Vuelva a instalar Monica Please
1
El problema con la sustitución de comandos $(find...)es que no hay forma de que el shell maneje los nombres de archivo con espacios en blanco u otros metacaracteres del shell en ellos. Si sabe que esto no es un problema, este enfoque está bien; pero hemos tenido demasiadas preguntas en las que las personas no fueron advertidas sobre este problema o no entendieron la advertencia.
Buena idea si trabaja dentro de un repositorio de git, ya que no corre el riesgo de sobrescribir .git / contenidos (como se informa en los comentarios a otra respuesta).
mahemoff
1
Gracias, lo uso como una función bash refactor() { echo "Replacing $1 by $2 in all files in this git repository." git grep -lz $1| xargs -0 perl -i'' -pE "s/$1/$2/g" }Uso, por ejemplo, para reemplazar 'palabra' con 'espada': refactor word swordluego verifique con qué hizo git diff.
Paul Rougieux
16
Para reducir los archivos de forma recursiva sed, podría greppara su instancia de cadena:
grep -rl <oldstring>/path/to/folder | xargs sed -i s^<oldstring>^<newstring>^g
Si ejecuta man grep, notará que también puede definir un--exlude-dir="*.git" indicador si desea omitir la búsqueda a través de directorios .git, evitando problemas de índice git como otros han señalado cortésmente.
Llevándote a:
grep -rl --exclude-dir="*.git"<oldstring>/path/to/folder | xargs sed -i s^<oldstring>^<newstring>^g
Más sabio usar git-grepla -zopción junto con xargs -0.
gniourf_gniourf
git grepobviamente solo tiene sentido en un gitrepositorio. El reemplazo general sería grep -r.
tripleee
@gniourf_gniourf ¿Puedes explicarlo?
Petr Peller
2
@PetrPeller: with -z, git-grepseparará los campos de salida por bytes nulos en lugar de líneas nuevas; y con -0, xargsleerá la entrada separada por bytes nulos, en lugar de espacios en blanco (y no hará cosas raras con comillas). Así que si usted no quiere que la orden de descanso si los nombres de archivo contienen espacios, citas u otros caracteres extraños, el comando es: git grep -z -l 'original_text' | xargs -0 sed ....
gniourf_gniourf
10
find /home/www/-type f -exec perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g'{}+
find /home/www/ -type f enumerará todos los archivos en / home / www / (y sus subdirectorios). El indicador "-exec" le dice a find que ejecute el siguiente comando en cada archivo encontrado.
es el comando que se ejecuta en los archivos (muchos a la vez). El {}se reemplaza por nombres de archivo. Al +final del comando le indica findque cree un comando para muchos nombres de archivo.
Por el find página de manual: "La línea de comando se construye de la misma manera que xargs construye sus líneas de comando".
Por lo tanto, es posible lograr su objetivo (y manejar nombres de archivos que contienen espacios) sin usar xargs -0, o -print0.
Ack-grep es muy eficiente para encontrar archivos relevantes. Este comando reemplazó ~ 145 000 archivos con una brisa, mientras que otros tardaron tanto que no podía esperar hasta que terminaran.
Un método sencillo si necesita excluir directorios ( --exclude-dir=.svn) y también puede tener nombres de archivo con espacios (usando 0Byte con grep -Zyxargs -0
grep -rlZ oldtext .--exclude-dir=.svn | xargs -0 sed -i 's/oldtext/newtext/g'
grep -lr 'subdomainA.example.com' | while read file; do sed -i "s/subdomainA.example.com/subdomainB.example.com/g" "$file"; done
Supongo que la mayoría de las personas no saben que pueden canalizar algo en un "archivo mientras se lee" y evita esos desagradables argumentos -print0, mientras preseleccionan espacios en los nombres de archivo.
Además, agregar un echoantes del sed le permite ver qué archivos cambiarán antes de hacerlo realmente.
La razón -print0es útil porque maneja casos que while readsimplemente no pueden manejar: una nueva línea es un carácter válido en un nombre de archivo Unix, por lo que para que su código sea completamente robusto, también necesita hacer frente a dichos nombres de archivo. (Además, desea read -revitar un comportamiento legado molesto de POSIX en read.)
tripleee
Además, sedes un no-op si no hay coincidencias, por lo grepque no es realmente necesario; aunque es una optimización útil para evitar reescribir archivos que no contienen coincidencias, si tiene muchos de esos, o si desea evitar actualizar innecesariamente los sellos de fecha en los archivos.
tripleee
5
Puede usar awk para resolver esto de la siguiente manera,
Funciona en MacOs sin ningún problema! Todos los sedcomandos basados fallaron cuando se incluyeron archivos binarios incluso con la configuración específica de osx.
Jankapunkt
Cuidado ... esto explotará si alguno de los archivos finddevueltos tiene un espacio en sus nombres. Es mucho más seguro de usar while read: stackoverflow.com/a/9612560/1938956
Soren Bjornstad
4
Prueba esto:
sed -i 's/subdomainA/subdomainB/g'`grep -ril 'subdomainA' *`
Hola @RikHic, buen consejo: estaba pensando en algo como esto; desafortunadamente, el formato anterior no resultó bien :) Así que intentaré con una etiqueta previa (no funciona), por lo que con escapes de retroceso, entonces: sed -i 's/subdomainA/subdomainB/g'` grep -ril 'subdomainA' /home/www/*` - esto todavía no se ve muy bien, pero debería sobrevivir copypaste :) ¡Salud!
sdaau
4
#!/usr/local/bin/bash -x
find */home/www -type f |while read files
do
sedtest=$(sed -n '/^/,/$/p'"${files}"| sed -n '/subdomainA/p')if["${sedtest}"]then
sed s'/subdomainA/subdomainB/'g "${files}">"${files}".tmp
mv "${files}".tmp "${files}"fidone
grep recursivamente para la cadena que desea reemplazar en una ruta determinada, y tome solo la ruta completa del archivo coincidente. (ese sería el $(grep 'string' 'pathname' -Rl).
(opcional) si desea hacer una copia de seguridad previa de esos archivos en el directorio centralizado, puede usar esto también: cp -iv $(grep 'string' 'pathname' -Rl) 'centralized-directory-pathname'
después de eso, puede editar / reemplazar a voluntad vimsiguiendo un esquema similar al proporcionado en el enlace proporcionado:
Un poco vieja escuela, pero esto funcionó en OS X.
Hay algunos trucos:
• Solo editará archivos con extensión .sls bajo el directorio actual
• .debe escaparse para garantizarsed que no los evalúa como "cualquier personaje"
• ,se usa como seddelimitador en lugar del habitual/
También tenga en cuenta que esto es para editar una plantilla Jinja para pasar un variableen la ruta de un import(pero esto está fuera de tema).
Primero, verifique que su comando sed haga lo que desea (esto solo imprimirá los cambios en stdout, no cambiará los archivos):
for file in $(find .-name *.sls -type f);do echo -e "\n$file: "; sed 's,foo\.bar,foo/bar/\"+baz+\"/,g' $file;done
Edite el comando sed según sea necesario, una vez que esté listo para realizar cambios:
for file in $(find .-name *.sls -type f);do echo -e "\n$file: "; sed -i '''s,foo\.bar,foo/bar/\"+baz+\"/,g' $file;done
Tenga -i ''en cuenta que en el comando sed , no quería crear una copia de seguridad de los archivos originales (como se explica en Ediciones in situ con sed en OS X o en el comentario de Robert Lujo en esta página).
más uno para '' *. [c | cc | cp | cpp | m | mm | h] ''
FractalSpace
2
Aquí hay una versión que debería ser más general que la mayoría; no requiere find(usando en su dulugar), por ejemplo. Requiere xargs, que solo se encuentran en algunas versiones del Plan 9 (como 9front).
du -a | awk -F' ''{ print $2 }'| xargs sed -i -e 's/subdomainA\.example\.com/subdomainB.example.com/g'
Si desea agregar filtros como extensiones de archivo, use grep:
du -a | grep "\.scala$"| awk -F' ''{ print $2 }'| xargs sed -i -e 's/subdomainA\.example\.com/subdomainB.example.com/g'
Esto tiene algunos problemas molestos con las citas y con las líneas de lectura for.
tripleee
1
Si desea utilizar esto sin destruir por completo su repositorio SVN, puede decirle a 'buscar' que ignore todos los archivos ocultos haciendo lo siguiente:
find . \( !-regex '.*/\..*' \) -type f -print0 | xargs -0 sed -i 's/subdomainA.example.com/subdomainB.example.com/g'
Los paréntesis parecen ser superfluos. Esto anteriormente tenía un error de formato que lo dejaba inutilizable (la representación de Markdown consumiría algunos caracteres de la expresión regular).
tripleee
1
Usando la combinación de grepysed
for pp in $(grep -Rl looking_for_string)do
sed -i 's/looking_for_string/something_other/g'"${pp}"done
@tripleee Modifiqué esto un poco. En este caso, la salida para el comando grep -Rl patterngeneró la lista de archivos donde está el patrón. Los archivos no se leen en forbucle.
Pawel
¿Eh? Aún tienes un forbucle; si algún nombre de archivo devuelto contiene espacios en blanco, no funcionará correctamente porque el shell tokeniza la forlista de argumentos. Pero luego usa la variable de nombre de archivo sin comillas dentro del bucle, por lo que se rompería allí si solucionara esto. Corregir estos errores restantes haría que los suyos fueran idénticos a la respuesta de @ MadMan2064.
tripleee
@tripleee sí, eso es cierto, me perdí esto.
Pawel
1
Para reemplazar todas las ocurrencias en un repositorio de git puede usar:
git ls-files -z | xargs -0 sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g'
Ver Lista de archivos en el repositorio local de git? para otras opciones para enumerar todos los archivos en un repositorio. Las -zopciones le dicen a git que separe los nombres de los archivos con un byte cero, lo que asegura que xargs(con la opción -0) puede separar los nombres de los archivos, incluso si contienen espacios o no.
-path ./.git -prune -o
defind . -path ./.git -prune -o -type f -name '*matchThisText*' -print0
antes del conexionado a xargsRespuestas:
-print0
le dicefind
que imprima cada uno de los resultados separados por un carácter nulo, en lugar de una nueva línea. En el caso improbable de que su directorio tenga archivos con nuevas líneas en los nombres, esto todavía permitexargs
trabajar con los nombres de archivo correctos.\( -type d -name .git -prune \)
es una expresión que omite completamente todos los directorios nombrados.git
. Puede expandirlo fácilmente, si usa SVN o tiene otras carpetas que desea preservar, solo haga coincidir con más nombres. Es más o menos equivalente a-not -path .git
, pero más eficiente, porque en lugar de verificar cada archivo en el directorio, lo omite por completo. El-o
after se requiere debido a cómo-prune
funciona realmente.Para más información, ver
man find
.fuente
sed: 1: "...": invalid command code .
problemas. Parece que la opción -i espera una extensión y analiza el's/../...'
comando. Solución: pase la extensión '' a la opción -i comosed -i '' 's/...
.svn st
no muestra cambios, ¡es porque también ha modificado los archivos en los directorios .svn! Usar en sufind . -maxdepth 1 -type f -print0 | xargs -0 sed -i 's/toreplace/replaced/g'
lugar.grep -r 'hello' -l --null . | xargs -0 sed -i 's#hello#world#g'
para evitar editar archivos no relacionados (sed podría cambiar la codificación del archivo).find .git ... | ... 'sed -i s/(the opposite from before)/g'
para corregir su índice gitNota : No ejecute este comando en una carpeta que incluya un repositorio git; los cambios en .git podrían dañar su índice git.
En comparación con otras respuestas aquí, esto es más simple que la mayoría y usa sed en lugar de perl, que es lo que preguntó la pregunta original.
fuente
-i
opción de sed . es decir:sed -i '' 's/original/replacement/g'
+
Reduce en gran medida el número desed
procesos generados. Es mas eficiente.find . -not -path '*/\.git*' -type f ...
.La forma más simple para mí es
fuente
-I
o--binary-file=without-match
grep..svn
. Por ejemplo:grep -rl oldtext . --exclude-dir=.svn | xargs sed -i 's/oldtext/newtext/g'
brew install gnu-sed
y usargsed
en OSX para evitar un mundo de dolor.git grep -rl oldtext . | xargs sed -i 's/oldtext/newtext/g'
. no es nada agradable joder tu.git
directorioTodos los trucos son casi iguales, pero me gusta este:
find <mydir>
: busca en el directorio.-type f
:-exec command {} +
:fuente
file
comando para intentar determinar el tipo de cada archivo, pero las variaciones accidentales en su salida pueden ser un poco desconcertantes. La opción-I
(aka--mime
) ayuda un poco, o--mime-type
si la tiene. Lamentablemente, cómo refactorizar esta simple línea para hacer esto está lamentablemente fuera del alcance de este pequeño cuadro de comentarios. Tal vez publicar una pregunta por separado si necesita ayuda? (Tal vez agregue un comentario con un enlace aquí.)fuente
-print0
y enxargs
lugar de-exec
o-execdir
?find -exec command {} +
evita invocaciones excesivas del comando como xargs, pero sin el proceso por separado.find -exec ... {} +
se ha especificado en POSIX desde 2006.Para mí, la solución más fácil de recordar es https://stackoverflow.com/a/2113224/565525 , es decir:
NOTA :
-i ''
resuelve el problema de OSXsed: 1: "...": invalid command code .
NOTA : Si hay demasiados archivos para procesar, obtendrá
Argument list too long
. La solución alternativa: usofind -exec
oxargs
solución descrita anteriormente.fuente
workaround
debe ser la sintaxis preferida en todos los casos.$(find...)
es que no hay forma de que el shell maneje los nombres de archivo con espacios en blanco u otros metacaracteres del shell en ellos. Si sabe que esto no es un problema, este enfoque está bien; pero hemos tenido demasiadas preguntas en las que las personas no fueron advertidas sobre este problema o no entendieron la advertencia.Para cualquiera que use el buscador plateado (
ag
)Dado que ag ignora los archivos / carpetas git / hg / svn de forma predeterminada, es seguro ejecutarlo dentro de un repositorio.
fuente
Un buen oneliner como extra. Usando git grep.
fuente
refactor() { echo "Replacing $1 by $2 in all files in this git repository." git grep -lz $1| xargs -0 perl -i'' -pE "s/$1/$2/g" }
Uso, por ejemplo, para reemplazar 'palabra' con 'espada':refactor word sword
luego verifique con qué hizogit diff
.Para reducir los archivos de forma recursiva
sed
, podríagrep
para su instancia de cadena:Si ejecuta
man grep
, notará que también puede definir un--exlude-dir="*.git"
indicador si desea omitir la búsqueda a través de directorios .git, evitando problemas de índice git como otros han señalado cortésmente.Llevándote a:
fuente
Este es compatible con repositorios git, y un poco más simple:
Linux:
Mac:
(Gracias a http://blog.jasonmeridth.com/posts/use-git-grep-to-replace-strings-in-files-in-your-git-repository/ )
fuente
git-grep
la-z
opción junto conxargs -0
.git grep
obviamente solo tiene sentido en ungit
repositorio. El reemplazo general seríagrep -r
.-z
,git-grep
separará los campos de salida por bytes nulos en lugar de líneas nuevas; y con-0
,xargs
leerá la entrada separada por bytes nulos, en lugar de espacios en blanco (y no hará cosas raras con comillas). Así que si usted no quiere que la orden de descanso si los nombres de archivo contienen espacios, citas u otros caracteres extraños, el comando es:git grep -z -l 'original_text' | xargs -0 sed ...
.find /home/www/ -type f
enumerará todos los archivos en / home / www / (y sus subdirectorios). El indicador "-exec" le dice a find que ejecute el siguiente comando en cada archivo encontrado.es el comando que se ejecuta en los archivos (muchos a la vez). El
{}
se reemplaza por nombres de archivo. Al+
final del comando le indicafind
que cree un comando para muchos nombres de archivo.Por el
find
página de manual: "La línea de comando se construye de la misma manera que xargs construye sus líneas de comando".Por lo tanto, es posible lograr su objetivo (y manejar nombres de archivos que contienen espacios) sin usar
xargs -0
, o-print0
.fuente
Solo necesitaba esto y no estaba contento con la velocidad de los ejemplos disponibles. Entonces se me ocurrió el mío:
Ack-grep es muy eficiente para encontrar archivos relevantes. Este comando reemplazó ~ 145 000 archivos con una brisa, mientras que otros tardaron tanto que no podía esperar hasta que terminaran.
fuente
grep -ril 'subdomainA' *
no es tan rápido comogrep -Hr 'subdomainA' * | cut -d: -f1
.Un método sencillo si necesita excluir directorios (
--exclude-dir=.svn
) y también puede tener nombres de archivo con espacios (usando 0Byte congrep -Z
yxargs -0
fuente
La forma más simple de reemplazar ( todos los archivos, directorio, recursivo )
Nota: a veces es posible que deba ignorar algunos archivos ocultos, es decir
.git
, puede usar el comando anterior.Si desea incluir el uso de archivos ocultos,
En ambos casos, la cadena
foo
se reemplazará por una nueva.bar
fuente
grep -lr 'subdomainA.example.com' | while read file; do sed -i "s/subdomainA.example.com/subdomainB.example.com/g" "$file"; done
Supongo que la mayoría de las personas no saben que pueden canalizar algo en un "archivo mientras se lee" y evita esos desagradables argumentos -print0, mientras preseleccionan espacios en los nombres de archivo.
Además, agregar un
echo
antes del sed le permite ver qué archivos cambiarán antes de hacerlo realmente.fuente
-print0
es útil porque maneja casos quewhile read
simplemente no pueden manejar: una nueva línea es un carácter válido en un nombre de archivo Unix, por lo que para que su código sea completamente robusto, también necesita hacer frente a dichos nombres de archivo. (Además, desearead -r
evitar un comportamiento legado molesto de POSIX enread
.)sed
es un no-op si no hay coincidencias, por logrep
que no es realmente necesario; aunque es una optimización útil para evitar reescribir archivos que no contienen coincidencias, si tiene muchos de esos, o si desea evitar actualizar innecesariamente los sellos de fecha en los archivos.Puede usar awk para resolver esto de la siguiente manera,
Espero que esto te ayudará !!!
fuente
sed
comandos basados fallaron cuando se incluyeron archivos binarios incluso con la configuración específica de osx.find
devueltos tiene un espacio en sus nombres. Es mucho más seguro de usarwhile read
: stackoverflow.com/a/9612560/1938956Prueba esto:
fuente
sed -i 's/subdomainA/subdomainB/g'
`grep -ril 'subdomainA' /home/www/*
` - esto todavía no se ve muy bien, pero debería sobrevivir copypaste :) ¡Salud!fuente
Según esta publicación de blog:
fuente
/
? Por ejemplo, quiero reemplazar las direcciones IP:xxx.xxx.xxx.xxx
paraxxx.xxx.xxx.xxx/folder
/
con \. Por ejemplo:find . -type f | xargs perl -pi -e 's/xxx.xxx.xxx.xxx\/folder/newtext/g;'
Si no le importa usar
vim
junto congrep
ofind
herramientas, puede seguir la respuesta dada por el usuario Gert en este enlace -> ¿Cómo hacer un reemplazo de texto en una jerarquía de carpetas grandes?.Aquí está el trato:
grep recursivamente para la cadena que desea reemplazar en una ruta determinada, y tome solo la ruta completa del archivo coincidente. (ese sería el
$(grep 'string' 'pathname' -Rl)
.(opcional) si desea hacer una copia de seguridad previa de esos archivos en el directorio centralizado, puede usar esto también:
cp -iv $(grep 'string' 'pathname' -Rl) 'centralized-directory-pathname'
después de eso, puede editar / reemplazar a voluntad
vim
siguiendo un esquema similar al proporcionado en el enlace proporcionado::bufdo %s#string#replacement#gc | update
fuente
Un poco vieja escuela, pero esto funcionó en OS X.
Hay algunos trucos:
• Solo editará archivos con extensión
.sls
bajo el directorio actual•
.
debe escaparse para garantizarsed
que no los evalúa como "cualquier personaje"•
,
se usa comosed
delimitador en lugar del habitual/
También tenga en cuenta que esto es para editar una plantilla Jinja para pasar un
variable
en la ruta de unimport
(pero esto está fuera de tema).Primero, verifique que su comando sed haga lo que desea (esto solo imprimirá los cambios en stdout, no cambiará los archivos):
Edite el comando sed según sea necesario, una vez que esté listo para realizar cambios:
Tenga
-i ''
en cuenta que en el comando sed , no quería crear una copia de seguridad de los archivos originales (como se explica en Ediciones in situ con sed en OS X o en el comentario de Robert Lujo en esta página).¡Felices amigos!
fuente
solo para evitar cambiar también
pero aún
(tal vez no sea bueno en la idea detrás del dominio raíz)
fuente
Solo uso tops:
fuente
Aquí hay una versión que debería ser más general que la mayoría; no requiere
find
(usando en sudu
lugar), por ejemplo. Requierexargs
, que solo se encuentran en algunas versiones del Plan 9 (como 9front).Si desea agregar filtros como extensiones de archivo, use
grep
:fuente
Para Qshell (qsh) en IBMi, no bash como lo etiqueta OP
Limitaciones de los comandos qsh:
Así, la solución en qsh:
Advertencias:
fuente
for
.Si desea utilizar esto sin destruir por completo su repositorio SVN, puede decirle a 'buscar' que ignore todos los archivos ocultos haciendo lo siguiente:
fuente
Usando la combinación de
grep
ysed
fuente
grep -Rl pattern
generó la lista de archivos donde está el patrón. Los archivos no se leen enfor
bucle.for
bucle; si algún nombre de archivo devuelto contiene espacios en blanco, no funcionará correctamente porque el shell tokeniza lafor
lista de argumentos. Pero luego usa la variable de nombre de archivo sin comillas dentro del bucle, por lo que se rompería allí si solucionara esto. Corregir estos errores restantes haría que los suyos fueran idénticos a la respuesta de @ MadMan2064.Para reemplazar todas las ocurrencias en un repositorio de git puede usar:
Ver Lista de archivos en el repositorio local de git? para otras opciones para enumerar todos los archivos en un repositorio. Las
-z
opciones le dicen a git que separe los nombres de los archivos con un byte cero, lo que asegura quexargs
(con la opción-0
) puede separar los nombres de los archivos, incluso si contienen espacios o no.fuente
fuente
awk
/sed
, pero perl es común (excepto sistemas integrados / con solo busybox).para cambiar varios archivos (y guardar una copia de seguridad como
*.bak
):tomará todos los archivos en el directorio y los reemplazará
|
con x llamado "pastel de Perl" (fácil como un pastel)fuente