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 findadmite, esto se puede reducir a
find . -type f -name 'file*' -exec mv {} {}_renamed \;
La xargsversión es útil cuando no se usa {}, como en
find .... -print0 | xargs --null rm
Aquí rmse llama una vez (o con muchos archivos varias veces), pero no para cada archivo.
Eliminé la basenamepregunta en ti, porque probablemente esté mal: te moverías foo/bar/file8a file8_renamed, no foo/bar/file8_renamed.
Ediciones (como se sugiere en los comentarios):
- Agregado acortado
findsinxargs
- Adhesivo de seguridad agregado
xsea inútil: lafind . -type f -name 'file*' -exec mv {} "{}_renamed" \;xargsversión tiene la misma eficiencia que el primer ejemplo /xestá 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 defindsoporte de la{}_renamedconstrucción. (3) No entiendo su declaración quexargses útil para eliminar archivos (en contraste con renombrarlos).xargsno esmvvs.rm, sino el uso de{}vs. sin. El primero es similar amv file1 file1_renamed; mv file2 file2_renamedmientras 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
findimplementaciones que admiten-execdiry{}no en su conjunto, también es la más segura. Sin embargo, es posible que desee agregar un-itomv(y-Tsi lomvadmite)mvde un mensaje, o además de esto, puede (sin duda dependiendo de si su implementación defindsoporte) también puede usar lo-okdirque generará el comando que se ejecutará antes de ejecutarlo.-depthtambién es una buena idea si también va a tocar los nombres de directorio.-execdirtiene un inconveniente muy molesto, sefindniega a hacer cualquier cosa siPATHcontiene algún camino relativo ... askubuntu.com/questions/621132/…find: The relative path XXX is included in the PATH environmentOtro enfoque es usar un
while readbucle sobre lafindsalida. 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 -cproceso separado usandofindla-execopción 's .Y si el shell que se utiliza admite la
-dopción de especificar unreaddelimitador, 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:
--nullIndica que cada argumento pasadostdintermina 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 elmvcomando.-I replace-strCada ocurrencia dereplace-strserá reemplazada por el argumento leídostdin. Por lo tanto, puede cambiarlo por otra cadena si lo necesita.fuente
pringf "%f\0"lugar de unprint0?-print0producirá./prefijos siPATTERNcontiene 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.txta00 - foo.txt,1 - bar.txta01 - bar.txtetc.)Yo era capaz de hacer algo similar con el
for,findymv.Esto busca todos los
config.ymlarchivos y los renombra aconfig.yml.bakfuente
fory realizar una operación masiva.