Necesito reemplazar una cadena en muchos archivos en una carpeta, con solo ssh
acceso al servidor. ¿Cómo puedo hacer esto?
461
cd /path/to/your/folder
sed -i 's/foo/bar/g' *
Las apariciones de "foo" serán reemplazadas por "bar".
En los sistemas BSD como macOS, debe proporcionar una extensión de respaldo como -i '.bak'
"riesgo de corrupción o contenido parcial" según la página de manual.
cd /path/to/your/folder
sed -i '.bak' 's/foo/bar/g' *
sed
,-i
requiere una cadena después, que se agrega a los nombres de archivo antiguos. Entoncessed -i .bak 's/foo/bar/g' *.xx
mueve todos los.xx
archivos al.xx.bak
nombre equivalente y luego genera los.xx
archivos con la sustitución foo → barra.sed -i 's/foo\ with\ spaces/bar/g' *
. Supongo que te has enterado después de tanto tiempo ... pero de esta manera queda para que otros encuentren el mismo problema.sed -i -e 's/foo/bar/g' $(find /home/user/base/dir)
Similar a la respuesta de Kaspar pero con la bandera g para reemplazar todas las ocurrencias en una línea.
Para mayúsculas y minúsculas:
fuente
LC_ALL=C find ./ -type f -exec sed -i '' -e 's/proc.priv/priv/g' {} \;
(vea esta publicación y esta )--include=*.whatever
con -r.git/
. Asegúrese decd
bajar a un nivel inferior.git status
devuelve:error: bad index file sha1 signature.... fatal: index file corrupt
. ¿Lo que da?La respuesta de @ kev es buena, pero solo afecta a los archivos en el directorio inmediato. El siguiente ejemplo utiliza grep para buscar archivos de forma recursiva. A mí me funciona siempre.
Desglose de comandos
grep -r : --recursivo , lee recursivamente todos los archivos de cada directorio.
grep -l : --print-with-coincide , imprime el nombre de cada archivo que tiene una coincidencia, en lugar de imprimir líneas coincidentes.
grep -i : --ignore-case .
xargs : transforma el STDIN en argumentos, sigue esta respuesta .
El comando xargs -i @ ~ contiene @ ~ : un marcador de posición para el argumento que se utilizará en una posición específica en el comando ~ , el signo @ es un marcador de posición que podría reemplazarse por cualquier cadena.
sed -i : edita archivos en su lugar, sin copias de seguridad.
sed s / regexp / replace / : sustituye la expresión regular de coincidencia de cadenas con reemplazo .
sed s / regexp / replace / g : global , realice la sustitución de cada coincidencia en lugar de solo la primera coincidencia.
fuente
grep --include={*.php,*.html,*.js} -rnl './' -e "old-word" | xargs -i@ sed -i 's/old-word/new-word/g' @
|
, también, ¿-i
por qué en el comando xargs? Leí en el manual que está en desuso y debería usar-I
en lugar. ¿Y se@
usa como delimitador para el principio y el final del patrón?grep -rli 'old-word' * | xargs -I@ sed -i '' 's/2.0.0/latest/g' @
rli
) y el@
letrero, por ejemploEsto funcionó para mí:
Howerver, no hizo esto:
sed -i 's/string1/string2/g' *
. Tal vez "foo" no estaba destinado a ser string1 y "bar" no a string2.fuente
find ./ -type f -exec sed -i '' -e 's/string1/string2/' {} \;
Hay algunas respuestas estándar a esto ya enumeradas. En general, puede usar find para enumerar recursivamente los archivos y luego realizar las operaciones con sed o perl .
Para la mayoría de los usos rápidos, puede encontrar que el comando rpl es mucho más fácil de recordar. Aquí está el reemplazo (foo -> bar), recursivamente en todos los archivos:
rpl -R foo bar .
Probablemente necesites instalarlo (
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 búsqueda y reemplazo, la herramienta más general y poderosa que conozco es la respuesta , un pequeño script de Python que escribí hace un tiempo. tareas de cambio de nombre y refactorización más espinosas. Las razones por las que puede preferirlo son:
Para usarlo,
pip install repren
. Consulte el archivo README para ver ejemplos.fuente
Para reemplazar una cadena en varios archivos puede usar:
P.ej
Blog de origen
fuente
Para reemplazar una ruta dentro de los archivos (evitando caracteres de escape) puede usar el siguiente comando:
El signo @ significa que todos los caracteres especiales deben ignorarse en la siguiente cadena.
fuente
En caso de que su cadena tenga una barra diagonal (/), puede cambiar el delimitador a '+'.
Este comando se ejecutaría recursivamente en el directorio actual.
fuente
../domain.com
adomain.com
Las apariciones de la primera línea de "foo" serán reemplazadas por "bar". Y puede usar la segunda línea para verificar.
fuente
grep -rl 'foo' . | xargs sed -i 's/foo/bar/g'
Si tiene una lista de archivos que puede usar
Si tiene todos los archivos que puede usar
Si tiene una lista de archivos con extensión, puede usar
fuente
replace "old_string" "new_string" -- *.txt
replace
utilidad. Sin esta información, esta respuesta está incompleta."También podrías usar find y sed, pero creo que esta pequeña línea de perl funciona muy bien.
"(Extraído de http://www.liamdelahunty.com/tips/linux_search_and_replace_multiple_files.php )
Mis mejores resultados provienen del uso de perl y grep (para asegurar que el archivo tenga la expresión de búsqueda)
fuente
Dado que desea buscar la cadena
search
y reemplazarla conreplace
varios archivos, esta es mi fórmula de una línea probada en batalla :Explicación rápida de grep:
-R
- búsqueda recursiva-i
- insensible a mayúsculas y minúsculas-I
- saltar archivos binarios (quieres texto, ¿verdad?)-l
- Imprima una lista simple como salida. Necesario para los otros comandosLa salida grep se canaliza a sed (a través de xargs) que se usa para reemplazar el texto. La
-i
bandera alterará el archivo directamente. Elimínelo para una especie de modo "funcionamiento en seco".fuente
Hice mi propia solución antes de encontrar esta pregunta (y respuestas). Busqué diferentes combinaciones de "reemplazar" "varios" y "xml", porque esa era mi aplicación, pero no encontré esta en particular.
Mi problema: tenía archivos xml de primavera con datos para casos de prueba, que contenían objetos complejos. Un refactor en el código fuente de Java cambió muchas clases y no se aplicó a los archivos de datos XML. Para guardar los datos de los casos de prueba, necesitaba cambiar todos los nombres de clase en todos los archivos xml, distribuidos en varios directorios. Todo mientras guardo copias de seguridad de los archivos xml originales (aunque esto no era obligatorio, ya que el control de versiones me salvaría aquí).
Estaba buscando alguna combinación de
find
+sed
, porque funcionó para mí en otras situaciones, pero no con varios reemplazos a la vez.Luego encontré preguntar la respuesta de ubuntu y me ayudó a construir mi línea de comando:
Y funcionó perfectamente (bueno, mi caso tenía seis reemplazos diferentes). Pero tenga en cuenta que tocará todos los archivos * .xml en el directorio actual. Por eso, y si usted es responsable de un sistema de control de versiones, es posible que desee filtrar primero y solo pasar a
sed
aquellos que realmente tienen las cadenas que desea; me gusta:fuente
findstr /spin /c:"quéquieresbuscar" *.xml
será útil.fuente
Realmente cojo, pero no pude hacer que ninguno de los comandos sed funcionara correctamente en OSX, así que hice esta tontería:
^ - copie estas tres líneas en mi portapapeles (sí, incluya la nueva línea final), luego:
vi *
y mantenga presionado command-v hasta que diga que no quedan archivos.
Tonto ... hacky ... efectivo ...
fuente
En una MacBook Pro, utilicé lo siguiente (inspirado en https://stackoverflow.com/a/19457213/6169225 ):
fuente
-e
solo le dice a sed que el siguiente token es un comando. Para expresiones regulares extendidas, use-E
en su lugar.El editor de flujo modifica múltiples archivos "in situ" cuando se invoca con el
-i
interruptor, lo que toma un archivo de respaldo que termina como argumento. Entoncesreemplaza
foo
conbar
en todos los archivos en esta carpeta, pero no desciende en subcarpetas. Sin embargo, esto generará un nuevo.bak
archivo para cada archivo en su directorio. Para hacer esto de forma recursiva para todos los archivos en este directorio y todos sus subdirectorios, necesita un ayudante, comofind
, para atravesar el árbol de directorios.find
le permite más restricciones sobre qué archivos modificar, especificando argumentos adicionales comofind ./ -name '*.php' -or -name '*.html' -print0
, si es necesario.Nota: GNU
sed
no requiere un final de archivo,sed -i 's/foo/bar/g' *
también funcionará; FreeBSDsed
exige una extensión, pero permite un espacio intermedio, por lo quesed -i .bak s/foo/bar/g *
funciona.fuente
script para comando multiedit
A partir de la respuesta de Kaspar, hice un script bash para aceptar argumentos de línea de comando y, opcionalmente, limitar los nombres de archivo que coinciden con un patrón. Ahorre en su $ PATH y haga ejecutable, luego simplemente use el comando anterior.
Aquí está el guión:
fuente
Si el archivo contiene barras inclinadas invertidas (rutas generalmente), puede intentar algo como esto:
ex:
fuente
Para mantener mi nodo personal en inglés, escribí un script de utilidad que ayuda a reemplazar varios pares de cadenas viejas / nuevas, para todos los archivos en un directorio de forma recursiva.
Los múltiples pares de cadenas antiguas / nuevas se administran en un mapa hash.
El directorio se puede establecer a través de la línea de comando o la variable de entorno, el mapa está codificado en el script, pero puede modificar el código para cargarlo desde un archivo, si es necesario.
Requiere bash 4.2, debido a alguna nueva característica.
en_standardize.sh:
fuente
Usar el comando ack sería mucho más rápido así:
Además, si tiene un espacio en blanco en el resultado de la búsqueda. Necesitas escapar de eso.
fuente
Estoy dando un ejemplo para corregir un error común de shebang en las fuentes de Python.
Puedes probar el enfoque grep / sed. Aquí hay uno que funciona con GNU sed y no romperá un repositorio git:
O puedes usar greptile :)
Acabo de probar el primer script, y el segundo debería funcionar también. Tenga cuidado con los caracteres de escape, creo que debería ser más fácil usar greptile en la mayoría de los casos. Por supuesto, puede hacer muchas cosas interesantes con sed, y para eso puede ser preferible dominar su uso con xargs.
fuente
Encontré este de otra publicación (no recuerdo cuál) y, aunque no es el más elegante, es simple y, como usuario novato de Linux, no me ha causado problemas
si tiene espacios u otros caracteres especiales, use un \
para cadenas en subdirectorios use **
fuente
El siguiente comando se puede usar para buscar primero los archivos y reemplazar los archivos:
Por ejemplo
fuente
Hay una manera más fácil mediante el uso de un archivo de script simple:
abra el archivo en gedit o un editor de su elección, yo uso gedit aquí.
Luego, en el editor, pegue lo siguiente en el archivo
Guarde el archivo, cierre gedit , luego salga de su terminal o simplemente ciérrelo y luego inícielo para poder cargar el nuevo script que agregó.
Navegue hasta el directorio donde tiene varios archivos que desea editar. Entonces corre:
Presione Intro y esto reemplazará automáticamente oldstring y oldstring1 en todos los archivos que los contienen con la cadena de noticias correcta y la cadena de noticias1 respectivamente.
Omitirá todos los directorios y archivos que no contengan las cadenas antiguas.
Esto podría ayudar a eliminar el tedioso trabajo de escribir en caso de que tenga varios directorios con archivos que necesitan reemplazo de cadena. Todo lo que tiene que hacer es navegar a cada uno de esos directorios, luego ejecutar:
#replace_string_files_present_dir
Todo lo que tiene que hacer es asegurarse de haber incluido o agregado todas las cadenas de reemplazo como le mostré anteriormente:
replace "oldstring" "newstring" -- *
al final del archivo / bin / replace_string_files_present_dir .
Para agregar una nueva cadena de reemplazo, simplemente abra el script que creamos escribiendo lo siguiente en el terminal:
sudo gedit /bin/replace_string_files_present_dir
No se preocupe por la cantidad de cadenas de reemplazo que agregue, no tendrán efecto si no se encuentra la cadena antigua .
fuente
.gitlab-ci.yml
ao atravis.yml
). Cada vuelta que consiste en escribir un guión para ejecutarlo más tarde es un antipatrón, ya que luego necesitará guiar la creación del guión (y la mayoría de las veces me da problemas)$ reemplaza "From" "To" - `find / path / to / folder -type f`
(reemplazar - una utilidad de reemplazo de cadenas del sistema de base de datos MySQL)
fuente