Acoplar estructura de directorios

15

Tengo un montón de carpetas dentro de las carpetas. Me gusta esto

Root Folder
    -- Folder 1
    -- Folder 2
    -- Folder 3
    -- Folder 4

Quiero contraer todas las carpetas para que todos los archivos en la carpeta 1, carpeta 2, carpeta 3, ... carpeta n existan en la carpeta raíz.

¿Cuál es la forma más rápida de hacer esto en Windows?

Más de cinco
fuente
55
Depende, ¿cómo le gustaría manejar nombres de archivos duplicados?
Mark Allen

Respuestas:

19

No hay razón para usar herramientas especiales o incluso secuencias de comandos. Solo usa la función de búsqueda en Explorer.

  1. Abra la carpeta que desea aplanar en el Explorador.
  2. Cree una nueva carpeta, seleccione todos los archivos (pero no las carpetas) y arrástrelos a esa carpeta (esto evitará obtener dos copias de esos archivos).
  3. En el cuadro de búsqueda (el que está a la derecha de la barra de direcciones), escribe *y presiona Enter.
  4. Después de que se complete la lista, haga clic derecho y seleccione todo, luego haga clic derecho y Cortar.
  5. Presione el botón Atrás para volver a la carpeta original, luego haga clic derecho y pegue.
  6. Si tiene nombres duplicados, se le preguntará cómo lidiar con esto. Elija la opción más adecuada para su caso de uso. (Supongo que sería copiar ambos archivos). Para evitar que se le vuelva a preguntar, asegúrese de aplicar esto a todos los archivos con la casilla de verificación en la parte inferior.
  7. Seleccione todas las carpetas, asegúrese de que estén vacías mirando la ventana emergente sobre la cantidad de archivos seleccionados y luego elimínelas.

Si prefiere tener un script para poder iniciarlo y olvidarlo, también puede hacerlo. El comando para reemplazar mv *\* .es bastante fácil ( for /r %f in (*.*) do @move "%~f" .) pero estoy seguro de que le gustaría manejar duplicados, sin dejarlos atrás como en la respuesta de @Nicole Hamilton. Agregar un número al nombre de archivo de duplicados es probablemente la forma más fácil de hacerlo.

Copie y pegue el siguiente archivo por lotes en el Bloc de notas y guárdelo como "flatten.cmd" (incluidas las comillas):

@echo off
cd "%~1"
md tempryfolder
move *.* tempryfolder
for /r %%f in ("*.*") do call :START "%%~f"
for /r /d %%f in (*.*) do rd "%%~f" 
GOTO :EOF
:START
setlocal
If exist "%~n1%~x1" set /a num=2
:LOOP
If exist "%~n1%num%%~x1" (
    set /a num+=1
    goto loop
)
move "%~1" "%~n1%num%%~x1"

Para usar el script, simplemente arrastre la carpeta que desea aplanar encima.

trlyly
fuente
1
Similar pero más fácil de entender: superuser.com/a/523854/433830
aparente001
Nota: este script es esencialmente una bomba tenedor. Lo estoy usando en una carpeta con miles de subdirectorios y decenas de miles de subarchivos y la huella de memoria aumenta lentamente. No creo que vaya a encontrarme con problemas de OOM, pero es algo a tener en cuenta.
Nzall
@Nzall No tengo ningún problema en creer que podría hacer eso, pero culparía a Microsoft, no a mi código. Todo lo que hago es llamar a una subrutina en el archivo por lotes varias veces. Y nunca ejecuto más de uno a la vez: cada subrutina se ejecuta hasta su finalización, ejecutando solo un proceso a la vez. ¿Cuánta memoria estamos hablando de ser usado?
Trlyly
@trlkly En un momento llegó a 2 GB, aunque tenía una gran cantidad de carpetas y subcarpetas, alrededor de 75,000 archivos y miles de carpetas. Unos momentos después volvió a caer a unos 8-900 MB. Sin embargo, había muchos archivos duplicados. Estaba acoplando 12 copias de una biblioteca Javascript de 7,500 archivos para poder probar cómo cierto software manejaría una carpeta con decenas de miles de archivos.
Nzall
@Nzall Eso es increíblemente extraño para mí. Nada de lo que hace el script debería hacer eso. Es una subrutina que reutiliza una sola variable para incrementar el archivo. Puede que tenga que preguntar qué podría causar un uso de memoria tan grande en SO o algo así.
Trlyly
9

Puede aplanar en el Explorador de Windows navegando a la carpeta que desea aplanar y buscando System.Kind:<>folderexcluir carpetas de los resultados.

Luego puede seleccionar todos los archivos con CTRL + A y copiarlos y pegarlos en una nueva carpeta. Tenga en cuenta que el Explorador de Windows le preguntará cómo tratar con nombres de archivos duplicados.

ingrese la descripción de la imagen aquí

Mateo
fuente
1
tenga en cuenta que para que esto funcione, debe escribir "carpeta" en la traducción localizada correspondiente (por ejemplo, en italiano System.Kind:<>cartella)
JohnKiller
0

Este tipo de cosas es fácil con un shell de Unix. Esto es lo que podría hacer con mi propio shell Hamilton C (incluida la versión gratuita ). Podría hacer algo muy similar con Cygwin bash.

mv *\* .

Si su directorio es realmente enorme, es posible que se convierta en comodín en una línea de comando demasiado larga para que Windows pase a un proceso secundario. (La llamada a Windows CreateProcess limita la lista de argumentos a 32K caracteres Unicode). Pero el shell C no tiene límite internamente, por lo que podría iterar sobre la lista completa de esta manera:

foreach i ( *\* )
   mv $i .
end

Para el punto de @ MarkAllen anterior, este tipo de asume que no hay nombres duplicados. Si las hay, las copias posteriores de la lista sobrescribirán las anteriores. Si eso es un problema, puede iterar sobre los archivos, mv'solo si no está sobrescribiendo. El :toperador es el operador de cola . El -eoperador es el archivo existe prueba .

foreach i ( *\* )
   if ( -e $i:t ) then
      echo -2 $i not moved because it already exists
   else
      mv $i .
   end
end

Esto todavía deja los directorios vacíos, que tal vez no desee después de que se hayan vaciado. Esa podría ser la próxima iteración si importara.

Nicole Hamilton
fuente
Usando cygwin> mv *. mv: no puede stat `* ': No existe tal archivo o directorio
Más de cinco
En Cygwin bash, mv */* .funciona para mí.
Nicole Hamilton
3
Algunas personas están tan fijas en UNIXism ... Si realmente quieres hacer scripts en Windows 7, hay PowerShell, no necesitas un simulador de bash falso como Cygwin.
Ni siquiera necesitas PowerShell. La línea de comando regular todavía existe y puede hacer lo mismo. Vea mi respuesta a continuación.
Trlyly