una texto sustituir subcadena script reemplazar para linea extraer especiales eliminar completa caracteres caracter cadena buscar bash

bash - texto - Buscar+reemplazar cadenas en nombres de archivos



sed reemplazar linea completa (2)

Ambas variaciones mostradas aquí funcionan correctamente en la estructura de prueba de OPs:

find . -depth -name ''*foo*'' -execdir bash -c ''mv -i "$1" "${1//foo/bar}"'' bash {} /;

o, si tiene una gran cantidad de archivos y desea que se ejecute más rápido:

find . -depth -name ''*foo*'' -execdir bash -c ''for f; do mv -i "$f" "${f//foo/bar}"; done'' bash {} +

EDITAR : Como se señaló en los comentarios, mi respuesta anterior utilizando un comando de find que no usó la opción execdir y el rename tiene problemas para cambiar el nombre de los archivos en directorios que contienen foo en su nombre. Como se sugirió, he cambiado los comandos de búsqueda para usar -execdir , y he eliminado la variación utilizando el comando rename ya que no es un comando estándar.

Usando bash, ¿cómo puedo buscar todas las apariciones de la subcadena ''foo'' en todos los nombres de archivo (incluidas las carpetas) contenidos recursivamente en un directorio y reemplazarlos con ''barra''?

Por ejemplo, si la estructura actual se ve así:

-foo_test - fooo.txt - xfoo - yfoo.h - 1foo.c

Debería verse así después de ejecutar el script bash:

-bar_test - baro.txt - xbar - ybar.h - 1bar.c


Esto fue complicado debido a los nombres de directorio con varias instancias de "foo". Cuando cambia ./foo_test/xfoo a ./bar_test/xbar todo lo que estaba en ./foo_test vuelve inaccesible. Así que primero cambié los nombres de archivo y luego cambié la última aparición de "foo" en los nombres de directorio. Agregué declaraciones de eco para rastrear lo que sucede durante el desarrollo. Usted puede, por supuesto, eliminarlos.

#!/bin/sh #first change the file names #append ''.'' to process files in current directory for D in $(find -d . -name "*foo*" -type d ) ''.'' do pushd $D >> /dev/null echo ''directory: '' "$D" for file in $(find . -name "*foo*" -type f -maxdepth 1) do echo '' change'' "$file" ''to'' `echo "$file" | sed s/foo/bar/g` mv "$file" `echo "$file" | sed s/foo/bar/g` done popd >> /dev/null done echo '''' #Now change the directory names for D in $(find -d . -name "*foo*" -type d ) do echo ''change'' "$D" ''to'' `echo "$D" | sed ''s//(.*/)foo//1bar/''` #change only the last occurance of foo mv "$D" `echo "$D" | sed ''s//(.*/)foo//1bar/''` done

No tengo dudas de que hay formas más cortas y elegantes de hacerlo (probablemente solo eliminando la mitad de las líneas de este script), pero estoy bastante seguro de que esto funciona.

EDITAR Los bucles idénticos eran una bandera roja. Esta versión solo se repite una vez. Recibes un mensaje intentando mv ''.'' ''.'' mv ''.'' ''.'' , pero se ignora con seguridad.

#!/bin/sh #first change the file names #append ''.'' to change file in current directory for D in $(find -d . -name "*foo*" -type d ) ''.'' do pushd $D >> /dev/null echo ''directory: '' "$D" for file in $(find . -name "*foo*" -type f -maxdepth 1) do echo '' change'' "$file" ''to'' `echo "$file" | sed s/foo/bar/g` mv "$file" `echo "$file" | sed s/foo/bar/g` done popd >> /dev/null echo ''change'' "$D" ''to'' `echo "$D" | sed ''s//(.*/)foo//1bar/''` #change only the last occurence of foo mv "$D" `echo "$D" | sed ''s//(.*/)foo//1bar/''` done