Cómo mover todos los archivos dentro de las subcarpetas actuales aquí


8

También tengo 50 carpetas con algunas subcarpetas, con más de 1000 archivos de audio en total. Necesito eliminar todas las subcarpetas y poner todos los archivos en el nivel actual. Intenté mv */* ./pero se queja: la lista de argumentos es demasiado larga

Respuestas:


7

Supongo que la extensión de sus archivos de audio es .mp3

find <AudioFolderPath> -name '*.mp3' -exec mv -it <YourTargetFolder> {} +

Notas:

  • Reemplace .mp3con la extensión de sus archivos de audio

  • Reemplace <AudioParentFolderPath>con la carpeta principal que contiene sus subcarpetas.

  • Reemplace <YourTargetFolder>con la ruta de la carpeta en la que necesita colocar todos los archivos.

  • Si los archivos de arrastre de diferentes subcarpetas tienen el mismo nombre, solo se moverá uno.

editar: Como dijo Costas : "El -iinterruptor se vuelve mvinteractivo, se le solicitará antes de sobrescribir los archivos existentes"


¿'-t' le permite especificar primero el destino? (ya que no tengo esta opción en mi "mv" aquí, solo puedo suponer que al poner primero la carpeta de destino y luego la lista de archivos para mover allí ... pero si no, esto intentará encajar en todos en el último nombre de archivo, dando una advertencia) tpodría ser para "objetivo"?
— Olivier Dulac

Sí, como dijiste, -tpermite especificar primero el destino. de la mvpágina del manual: -t, --target-directory=DIRECTORY move all SOURCE arguments into DIRECTORY
— Muhammad

1
tenga en cuenta que esta es la opción de GNU mv, y no está disponible en todos los equipos (al menos en algunos entornos de producción). Proporciono una solución más portátil, pero la suya funciona bien para Linux
— Olivier Dulac

sí @OlivierDulac, tienes razón, gracias por tu nota.
— Muhammad

4
find . -type f -mindepth 2 -exec mv -t ./ {} +

Tenga en cuenta que ese comando sobrescribirá cualquier archivo con el mismo nombre. Puede usar esto para que se le solicite antes de sobrescribir:

find . -type f -mindepth 2 -exec mv -it ./ {} +

Explicación

  • -type f : solo encuentra archivos regulares.
  • -mindepth 2 : encuentra solo archivos en subdirectorios.
  • -exec mv -it ./ {}: el -execmedio "ejecuta este comando en cada archivo encontrado". El {}será reemplazado con los nombres de los archivos. El -iconmutador se vuelve mvinteractivo, se le preguntará antes de sobrescribir los archivos existentes y -testablecerá el directorio de destino ./.
  • +: junte los archivos (en una línea de argumento) tantos como el shell puede operar con el comando para invocar los tiempos mínimos del comando (no uno por uno sino uno a varios).

Con respecto a otras eliminaciones de carpetas vacías, puede usar la misma recepción:

find . -type d -empty -delete

1
-type fselecciona solo archivos sin formato, excluyendo enlaces simbólicos, canalizaciones con nombre y similares. Para mover todos los archivos que no sean directorios, puede hacerlo ! -type d.
— jimmij

@jimmij Supongo que nadie almacena archivos de audio con el nombre de pipe u otra cosa. Si le preocupan los enlaces simbólicos, puede usar el -Lparámetro
— Costas

1
-ies estándar, -tes solo GNU (nada que ver con Linux, que es solo un núcleo que se encuentra en algunos sistemas GNU y no GNU)
— Stéphane Chazelas

Estoy de acuerdo con @ StéphaneChazelas: -tno existe en algunos sistemas (como un AIX no tan antiguo)
— Olivier Dulac

@OlivierDulac Es casi imposible encontrar una decisión para satisfacer a todos, por lo que las diferentes variantes son bienvenidas. Nadie le prohíbe cambiar la cadena afind . -type f -mindepth 2 -exec mv {} ./ \;
— Costas

2

Sí, ese es un límite en el tamaño acumulativo de argumentos y entorno pasados ​​a la execve()llamada del sistema al ejecutar un comando externo.

Con zsh, puedes usar su incorporado mven su lugar:

zmodload -F zsh/files +b:zf_mv
zf_mv ./*/* .

O use zargspara dividir la lista en fragmentos manejables:

autoload zargs
zargs -Ifiles ./*/* -- mv files .

Con ksh93:

command -x mv ./*/* .

Con GNU xargsy con GNU mvcon un shell donde printfestá integrado (la mayoría, mkshsiendo la excepción notable):

printf '%s\0' ./*/* | xargs -r0 mv -t .

Tenga en cuenta que OP desea mover solo archivos, no directorios, por lo que debe ocuparse de eso. En zshcaso de que pueda poner algunos calificadores globales , por ejemplo, (.)o (^/)después del último *.
— jimmij

0

Una solución bastante portátil podría ser:

buscar todos los archivos en cada subcarpeta y moverlos al directorio actual

find ./*/ -type f -print | xargs mv -i "{}" ./

Puede agregar un | egrep "\.au$|\.mp3$|\.ac3$"intermedio para asegurarse también de que los archivos que encontró son archivos con una extensión de audio (agregue tantas extensiones como sea necesario para cubrir todo tipo, solo proporciono 3 comunes)


En su caso no hay necesidad de llamar finden absoluto. Solo lo suficiente echooprintf
— Costas

@Costas: el OP menciona que hay tantos archivos que "*" no se puede expandir ... Aquí solo expando los 50 nombres de carpetas, y el resto es manejado por xargs
— Olivier Dulac

Pero findno resuelva el problema, pero xargssí.
— Costas
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.