La siguiente es una solución directa de su enfoque:
find . -type f -name 'file*' -exec sh -c 'x="{}"; mv "$x" "${x}_renamed"' \;
Sin embargo, esto es muy costoso si tiene muchos archivos coincidentes, porque inicia un nuevo shell (que ejecuta a mv
) para cada coincidencia. Y si tiene caracteres divertidos en cualquier nombre de archivo, esto explotará. Un enfoque más eficiente y seguro es este:
find . -type f -name 'file*' -print0 | xargs --null -I{} mv {} {}_renamed
También tiene la ventaja de trabajar con archivos con nombres extraños. Si lo find
admite, esto se puede reducir a
find . -type f -name 'file*' -exec mv {} {}_renamed \;
La xargs
versión es útil cuando no se usa {}
, como en
find .... -print0 | xargs --null rm
Aquí rm
se llama una vez (o con muchos archivos varias veces), pero no para cada archivo.
Eliminé la basename
pregunta en ti, porque probablemente esté mal: te moverías foo/bar/file8
a file8_renamed
, no foo/bar/file8_renamed
.
Ediciones (como se sugiere en los comentarios):
- Agregado acortado
find
sinxargs
- Adhesivo de seguridad agregado
x
sea inútil: lafind . -type f -name 'file*' -exec mv {} "{}_renamed" \;
xargs
versión tiene la misma eficiencia que el primer ejemplo /x
está allí solo para arreglar directamente el enfoque del autor de la pregunta.{}
directamente en unsh -c "…"
comando shell ( ); siempre debe pasarlo como argumento. (2) No todas las versiones defind
soporte de la{}_renamed
construcción. (3) No entiendo su declaración quexargs
es útil para eliminar archivos (en contraste con renombrarlos).xargs
no esmv
vs.rm
, sino el uso de{}
vs. sin. El primero es similar amv file1 file1_renamed; mv file2 file2_renamed
mientras que el segundo esrm file1 file2
.Después de probar la primera respuesta y jugar un poco con ella, descubrí que se puede hacer un poco más corto y menos complejo usando
-execdir
:Parece que también debería hacer exactamente lo que necesita.
fuente
find
implementaciones que admiten-execdir
y{}
no en su conjunto, también es la más segura. Sin embargo, es posible que desee agregar un-i
tomv
(y-T
si lomv
admite)mv
de un mensaje, o además de esto, puede (sin duda dependiendo de si su implementación defind
soporte) también puede usar lo-okdir
que generará el comando que se ejecutará antes de ejecutarlo.-depth
también es una buena idea si también va a tocar los nombres de directorio.-execdir
tiene un inconveniente muy molesto, sefind
niega a hacer cualquier cosa siPATH
contiene algún camino relativo ... askubuntu.com/questions/621132/…find: The relative path XXX is included in the PATH environment
Otro enfoque es usar un
while read
bucle sobre lafind
salida. Esto permite el acceso a cada nombre de archivo como una variable que se puede manipular sin tener que preocuparse por los costos adicionales / posibles problemas de seguridad de generar unsh -c
proceso separado usandofind
la-exec
opción 's .Y si el shell que se utiliza admite la
-d
opción de especificar unread
delimitador, puede admitir archivos con nombres extraños (por ejemplo, con una nueva línea) utilizando lo siguiente:fuente
Quiero ampliar la primera respuesta y tener en cuenta que esto no funcionará para agregar al nombre de archivo ya que el
./
prefijo de la ruta está presente en el argumento del nombre de archivo.Modificando la respuesta de Thomas Erker, considero que este es un enfoque más genérico
Opciones de xargs:
--null
Indica que cada argumento pasadostdin
termina con un carácter nulo (\0
). De esta forma, el nombre del archivo puede contener espacios; de lo contrario, cada palabra se tratará como un parámetro diferente para elmv
comando.-I replace-str
Cada ocurrencia dereplace-str
será reemplazada por el argumento leídostdin
. Por lo tanto, puede cambiarlo por otra cadena si lo necesita.fuente
pringf "%f\0"
lugar de unprint0
?-print0
producirá./
prefijos siPATTERN
contiene metacaracteres de shell que se interponen en el camino al cambiar el nombre a algo que prefija los nombres originales. (por ejemplo, cambiar el nombre0 - foo.txt
a00 - foo.txt
,1 - bar.txt
a01 - bar.txt
etc.)Yo era capaz de hacer algo similar con el
for
,find
ymv
.Esto busca todos los
config.yml
archivos y los renombra aconfig.yml.bak
fuente
for
y realizar una operación masiva.