Tengo un archivo, por ejemplo map.txt
, que contiene una lista de cadenas de búsqueda y sus reemplazos correspondientes:
search -> replacement
bigBone -> bb
fishMarket -> fm
dogCollar -> dc
...
Necesito realizar una búsqueda y reemplazo de todas las cadenas que coincidan con lo anterior para todos los archivos de forma recursiva en una carpeta, excepto los enlaces simbólicos. Sé cómo hacerlo uno a la vez como este:
$ find /some/folder -type f -exec sed -i 's/old_text/new_text/g' {} \;
¿Cómo puedo realizar esto a gran escala utilizando el mapeo anterior? he leídoesta pregunta, pero no lo entiendo del todo.
Respuesta1
Respuesta
Si no le preocupa la velocidad (esta es una tarea única), tal vez pueda intentar esto:
cat map.txt | while read line; do
neww=${line##* };
oldw=${line%% *};
find /some/folder -type f -exec sed -i "s/$oldw/$neww/g" {} \;
done
No es óptimo, lo sé... :-P
PD: ¡verifique en una carpeta de prueba para ver si funciona!
Explicación
Básicamente:
- Archivo gato map.txt.
- Lea cada línea y obtenga la palabra a reemplazar
$oldw
y el reemplazo$neww
. - Para cada par, ejecute el comando de búsqueda que ya estaba usando (observe las comillas dobles esta vez para permitir la sustitución de variables).
Acerca de la expansión de parámetros
Para configurar las variables $oldw
tenemos $neww
que obtener la primera y la última palabra de cada línea. Para hacerlo, utilizamos la expansión de parámetros (implementación pura de Bash), aunque podríamos haber usado otras formas de obtener la primera y la última palabra de la cadena (es decir, cut
o awk
).
${line##* }
: de la variableline
, elimine el patrón de prefijo más grande (doble#
), donde el patrón es cualquier carácter (*
) seguido de un espacio (). Entonces tenemos la última palabra en
line
.${line%% *}
: de la variableline
, elimine el patrón de sufijo más grande (doble%
), donde el patrón es un espacio () seguido de cualquier carácter (
*
). Entonces obtenemos la primera palabra enline
.
En este caso las palabras estaban separadas por un espacio, pero podríamos haber usado cualquier separador.
Respuesta2
A veces necesito buscar y reemplazar términos en archivos de configuración.
Escribí un script disponible en githubsandr - buscar y reemplazarque permite crear/utilizar un mapa y realizar reemplazos en archivos.
Un ejemplo de uso:
$ cat file
Voyez ce jeu exquis wallon, de graphie en kit mais bref. Portez ce vieux whisky au juge blond qui fume sur son île intérieure, à côté de l'alcôve ovoïde, où les bûches se consument dans l'âtre, ce qui lui permet de penser à la cænogenèse de l'être dont il est question dans la cause ambiguë entendue à Moÿ, dans un capharnaüm qui, pense-t-il, diminue çà et là la qualité de son œuvre. Prouvez, beau j
$ cat map.txt
wallon => WALLON
se => SE
penser => PENSER
beau => BEAU
$ cat file | ./sandr -a map.txt
Voyez ce jeu exquis WALLON, de graphie en kit mais bref. Portez ce vieux whisky au juge blond qui fume sur son île intérieure, à côté de l'alcôve ovoïde, où les bûches SE consument dans l'âtre, ce qui lui permet de PENSER à la cænogenèSE de l'être dont il est question dans la cauSE ambiguë entendue à Moÿ, dans un capharnaüm qui, penSE-t-il, diminue çà et là la qualité de son œuvre. Prouvez, BEAU j