El siguiente comando está cambiando correctamente el contenido de 2 archivos.
sed -i 's/abc/xyz/g' xaa1 xab1
Pero lo que tengo que hacer es cambiar dinámicamente varios de estos archivos y no sé los nombres de los archivos. Quiero escribir un comando que lea todos los archivos del directorio actual comenzando xa*y que seddebería cambiar el contenido del archivo.

sed -i 's/abc/xyz/g' xa*?Respuestas:
Mejor todavía:
porque nadie sabe cuántos archivos hay y es fácil romper los límites de la línea de comandos.
Esto es lo que sucede cuando hay demasiados archivos:
fuente
forcomando. Para protegerte de eso, deberías usarlofind ... | xargs ...forparaechoogrep?"$i"lugar de$ievitar la división de palabras en nombres de archivos con espacios. De lo contrario, esto es muy agradable.fores parte de la sintaxis del lenguaje, no solo una versión incorporada. Parased -i 's/old/new' *, la expansión de*TODO debe pasar como un arglista para sed, y estoy bastante seguro de que esto tiene que suceder antes de que elsedproceso pueda comenzar. Usando elforbucle, el arglista completo (la expansión de*) nunca se pasa como un comando, solo se almacena en la memoria del shell y se repite. Sin embargo, no tengo ninguna referencia para esto, solo parece probable que esa sea la diferencia. (Me encantaría saber de alguien más conocedor ...)Me sorprende que nadie haya mencionado el argumento -exec para buscar, que está destinado a este tipo de casos de uso, aunque comenzará un proceso para cada nombre de archivo coincidente:
Alternativamente, uno podría usar xargs, que invocará menos procesos:
O más simplemente use la
+variante exec en lugar de;en find para permitir que find proporcione más de un archivo por llamada de subproceso:fuente
find ./ -type f -name 'xa*' -exec sed -i '' 's/asd/dsg/g' {} \;esa es la ubicación del comando find./y un par de comillas simples-ipara OSX../es igual.y-isolo tiene el parámetro backupsuffix.-execopción de buscar junto con{} +es suficiente para resolver el problema como se indicó, y debería estar bien para la mayoría de los requisitos. Peroxargses una mejor opción en general porque también permite el procesamiento paralelo con la-popción. Cuando su expansión global es lo suficientemente grande como para desbordar la longitud de su línea de comando, es probable que también se beneficie de una aceleración en una ejecución secuencial.Podrías usar grep y sed juntos. Esto le permite buscar subdirectorios de forma recursiva.
fuente
grep -vpara evitar las carpetas gitgrep -rl <old> . | grep -v \.git | xargs sed -i 's/<old>/<new>/g'Esos comandos no funcionarán en el valor predeterminado
sedque viene con Mac OS X.De
man 1 sed:Intentó
y
Ambos funcionan bien.
fuente
@PaulR publicó esto como un comentario, pero la gente debería verlo como una respuesta (y esta respuesta funciona mejor para mis necesidades):
Esto funcionará para una cantidad moderada de archivos, probablemente del orden de decenas, pero probablemente no del orden de millones .
fuente
sed -i 's|auth-user-pass nordvpn.txt|auth-user-pass /etc/openvpn/nordvpn.txt|g' *.ovpn.Otra forma más versátil es usar
find:fuente
Estoy usando
findpara una tarea similar. Es bastante simple: tienes que pasarlo como argumento parasedesto:sed -i 's/EXPRESSION/REPLACEMENT/g' `find -name "FILE.REGEX"`De esta manera, no tiene que escribir bucles complejos, y es fácil ver qué archivos va a cambiar, solo ejecute
findantes de ejecutarsed.fuente
puedes hacer
el texto ' xxxx ' busca y lo reemplazará con ' aaaa '
fuente
Si puede ejecutar un script, esto es lo que hice para una situación similar:
Usando un diccionario / hashMap (matriz asociativa) y variables para el
sedcomando, podemos recorrer la matriz para reemplazar varias cadenas. La inclusión de un comodín en elname_patternpermitirá reemplazar en el lugar en los archivos con un patrón (esto podría ser algo asíname_pattern='File*.txt') en un directorio específico (source_dir). Todos los cambios están escritoslogfileen eldestin_dirPrimero, se declara la matriz de pares, cada par es una cadena de reemplazo, luego
WHAT1se reemplazará porFOR1yOTHER_string_to replacese reemplazará porstring replaceden el archivoFile.txt. En el bucle se lee la matriz, el primer miembro del par se recupera comoreplace_what=$iy el segundo comoreplace_for=$j. Elfindcomando busca en el directorio el nombre del archivo (que puede contener un comodín) y elsed -icomando reemplaza en el mismo archivo (s) lo que se definió previamente. Finalmente agregué ungreparchivo redirigido al archivo de registro para registrar los cambios realizados en los archivos.Esto funcionó para mí
GNU Bash 4.3sed 4.2.2y se basó en la respuesta de VasyaNovikov para Loop over tuples in bash .fuente