Свести структуру каталогов

15

У меня есть куча папок внутри папок. Как это

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

Я хочу свернуть все папки, чтобы все файлы в папке 1, папке 2, папке 3, ... папке n существовали в корневой папке.

Какой самый быстрый способ сделать это в Windows?

Больше пяти
источник
5
Это зависит от того, как вы хотите обрабатывать дубликаты имен файлов?
Марк Аллен

Ответы:

19

Нет причин использовать специальные инструменты или даже сценарии. Просто используйте функцию поиска в проводнике.

  1. Откройте папку, которую вы хотите сгладить в проводнике.
  2. Создайте новую папку, выберите все файлы (но не папки) и перетащите их в эту папку (это позволит избежать получения двух копий этих файлов.)
  3. В поле поиска (поле справа от адресной строки) введите *и нажмите Enter.
  4. После того, как список заполнится, щелкните правой кнопкой мыши и выберите все, затем щелкните правой кнопкой мыши и выберите Cut.
  5. Нажмите кнопку «Назад», чтобы вернуться в исходную папку, затем щелкните правой кнопкой мыши и вставьте.
  6. Если у вас есть дубликаты имен, вам будет предложено, как с этим бороться. Выберите наиболее подходящий вариант для вашего варианта использования. (Я предполагаю, что это будет копировать оба файла.) Чтобы избежать повторного запроса, обязательно примените это ко всем файлам с флажком внизу.
  7. Выберите все папки, убедитесь, что они пусты, посмотрите во всплывающем окне количество выбранных файлов, а затем удалите их.

Если вы предпочитаете иметь скрипт, чтобы вы могли просто запустить его и забыть, это также можно сделать. Команда для замены mv *\* .довольно проста ( for /r %f in (*.*) do @move "%~f" .), но я уверен, что вы хотели бы обработать дубликаты, не оставляя их позади, как в ответе @Nicole Hamilton. Добавление числа к имени файла дубликатов, вероятно, самый простой способ сделать это.

Скопируйте и вставьте следующий пакетный файл в Блокнот и сохраните его как «flatten.cmd» (включая кавычки):

@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"

Чтобы использовать сценарий, просто перетащите папку, которую вы хотите свести поверх нее.

trlkly
источник
1
Похоже, но проще для понимания: superuser.com/a/523854/433830
aparente001
Примечание: этот скрипт по сути является вилкой. Я использую его в папке с тысячами подкаталогов и десятками тысяч подфайлов, и объем памяти постепенно увеличивается. Я не думаю, что столкнусь с проблемами ООМ, но об этом нужно помнить.
Nzall
@Nzall У меня нет проблем с верой в то, что он может это сделать, но я бы обвинял Microsoft, а не мой код. Все, что я делаю, это вызываю подпрограмму в командном файле несколько раз. И я никогда не запускаю больше одного за раз: каждая подпрограмма запускается до завершения, запуская только один процесс за раз. Сколько памяти мы говорим об использовании?
trlkly
@trlkly В какой-то момент он поднялся до 2 ГБ, хотя у меня было довольно большое количество папок и подпапок, около 75 000 файлов и тысячи папок. Через несколько мгновений он снова упал до 8-900 МБ. Было множество дубликатов файлов. Я сплющил 12 копий библиотеки Javascript на 7500 файлов, чтобы я мог проверить, как определенное программное обеспечение будет обрабатывать папку с десятками тысяч файлов.
Nzall
@Nzall Это невероятно странно для меня. Ничто из сценария не должно этого делать. Это одна подпрограмма, которая повторно использует одну переменную для увеличения файла. Возможно, мне придется спросить, что может вызвать такое большое использование памяти на SO или что-то.
trlkly
9

Вы можете сгладить в проводнике Windows, перейдя к папке, которую вы хотите сгладить и поиска, System.Kind:<>folderчтобы исключить папки из результатов.

Затем вы можете выбрать все файлы с помощью сочетания клавиш CTRL + A, скопировать и вставить их в новую папку. Обратите внимание, что Windows Explorer спросит вас, как обращаться с дублирующимися именами файлов.

введите описание изображения здесь

Мэтью
источник
1
обратите внимание, что для этого вам нужно набрать «folder» в соответствующем локализованном переводе (например, на итальянском языке System.Kind:<>cartella)
JohnKiller
0

Это легко сделать с помощью оболочки Unix. Вот что вы можете сделать с моей собственной оболочкой Hamilton C (включая бесплатную версию ). Вы можете сделать что-то очень похожее с Cygwin bash.

mv *\* .

Если ваша директория действительно огромна, возможно, что из-за слишком длинного символа командной строки Windows не сможет передать дочерний процесс. ( Вызов Windows CreateProcess ограничивает список аргументов символами Unicode 32K.) Но оболочка C не имеет внутренних ограничений, поэтому вы можете перебирать весь список следующим образом:

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

К @ MarkAllen выше, этот вид предполагает, что нет повторяющихся имен. Если они есть, более поздние копии в списке перезапишут более старые. Если это проблема, вы можете перебирать файлы, используя mvих, только если вы не перезаписываете. :tОператор является оператором хвост . -eОператор является файл существует тест .

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

Это по-прежнему оставляет пустые каталоги, которые, возможно, вам не нужны после того, как они были очищены. Это может быть следующая итерация, если это имеет значение.

Николь Гамильтон
источник
Использование cygwin> mv *. mv: not stat `* ': нет такого файла или каталога
более 5
В Cygwin bash, mv */* .работает для меня.
Николь Гамильтон
3
Некоторые люди так увлечены UNIXism ... Если вы действительно хотите создавать скрипты в Windows 7, есть PowerShell, вам не нужен какой-то фиктивный симулятор bash, такой как Cygwin.
Вам даже не нужен PowerShell. Обычная командная строка все еще существует и может делать то же самое. Смотрите мой ответ ниже.
trlkly