Сведение файлов во вложенных папках в Windows 7 (cmd или PowerShell)

У меня есть большой объем файлов, организованных в очень иерархическую структуру папок. В этой структуре нужный мне файл всегда находится на самом нижнем уровне папок. Таким образом, я хотел бы сгладить каталог, чтобы упростить доступ к нужным мне файлам. Однако я хотел бы сохранить 2 более высоких уровня (человек и проект) структуры папок.

Вот пример каталога папки EXISTING:

  • Directory
    • Tom
      • Project 1
        • Subfolder Level A
          • FileA
        • ФайлB
      • Project 2
        • Subfolder Level C
          • FileC
        • ФайлD
    • Jerry
      • Project 1
        • Subfolder Level E
          • FileE

Вот пример каталога папки DESIRED:

  • Directory
    • Tom
      • Project 1
        • FileA
        • ФайлB
      • Project 2
        • FileC
        • ФайлD
    • Jerry
      • Project 1
        • FileE

Я пытался сделать что-то подобное, однако это объединяет все файлы в один каталог:

for /r %f in (*) do @copy "%f" .

Тем не менее, это производит:

  • Directory
    • FileA
    • ФайлB
    • ФайлC
    • ФайлD
    • ФайлE

Буду признателен за любые рекомендации, которые вы можете предложить. Большое спасибо!


person KingOfTheNerds    schedule 16.12.2014    source источник


Ответы (4)


Вот подход Powershell. Он получает список папок на нужном вам уровне. Затем он перемещает все подфайлы на этот уровень. он также удалит подпапки.

$Rootfolder = Dir directory\*\* -Directory 

ForEach($folder in $Rootfolder)
{
    Dir $folder.fullname -Recurse -File | Copy-Item -Destination $folder.fullname
    Dir $folder.fullname -Recurse -Directory | Remove-Item -Force -Recurse -WhatIf
}

Если вы хотите его удалить, удалите -WhatIf из последней строки.

person kevmar    schedule 17.12.2014

Добавьте пару дополнительных циклов for вокруг того, который тогда работает.

например Сначала перейдите в папку с именем, затем в папку проекта, проходя через оба уровня.

for /D %n in (*) do (
    pushd %n
    for /D %p in (*) do (
        pushd %p
        for /r %f in (*) do @copy "%f" .
        popd
    )
    popd
)

Если вы поместите это в файл bat, не забудьте заменить % на %%

person Scott C    schedule 16.12.2014
comment
После COPY вы можете добавить for /d %f in (*) do rd /s /q >nul, чтобы избавиться от нежелательных подпапок. - person dbenham; 17.12.2014
comment
Если вы хотите добавить очистку, то move файлы вместо copy и добавьте дополнительный оператор for (предложенный @dbenham) перед первым всплывающим окном. - person Scott C; 18.12.2014
comment
@ScottC - большое спасибо за помощь. Я использовал перемещение, но мне пришлось жестко закодировать часть пути, куда его перемещать. - person KingOfTheNerds; 18.12.2014
comment
@dbenham - спасибо за предложение. У меня возникли проблемы с выяснением, где внести это изменение, чтобы я также не удалял нужные мне файлы, однако я нашел эта утилита, которая, я думаю, удалит все теперь пустые папки. - person KingOfTheNerds; 18.12.2014
comment
@KingOfTheNerds - я думаю, что этому ответу нужен дополнительный цикл, чтобы он не пытался скопировать файл на себя. См. мой ответ - person dbenham; 18.12.2014
comment
@dbenham - ты прав. Это было попыткой скопировать файлы на себя. Я опубликую свое окончательное решение ниже (оно очень похоже на ваш исправленный код). Спасибо за помощь! - person KingOfTheNerds; 18.12.2014
comment
Мне пришлось использовать for /d %%f in (*) do rmdir %%f /s /q, чтобы удалить каталог - person gorlaz; 06.09.2016

@echo off
pushd yourDirectory
for /d %%A in (*) do for /d %%B in ("%%A\*") do for /d %%C in ("%%B\*") do (
  pushd "%%C"
  for /r %%F in (*) do move /y "%%F" "%%B" >nul
  popd
  rd /q /s "%%C"
)
popd

%%A содержит что-то вроде "yourDirectory\Tom"
%%B содержит что-то вроде "yourDirectory\Tom\Project 1"
%%C содержит что-то вроде "yourDirectory\Tom\Project 1\subdirectory1" % %F содержит файл для перемещения на любую глубину

Сначала я думал, что смогу исключить PUSHD/POPD и использовать

for /r "%%C" %%F in (*) do ...  THIS DOES NOT WORK

Но это не работает — значение после /R не может использовать переменную FOR или отложенное раскрытие из-за того, как анализируется команда.

person dbenham    schedule 18.12.2014

Я изменил ответ @ScottC и использовал следующий код:

for /D %%n in (*) do (
    pushd %%n
    for /D %%p in (*) do (
        pushd %%p
        for /r %%f in (*.ppt) do (
            move "%%f" "[ROOT_PATH_THAT_I_WANT]\%%n\%%p".
        )
        popd
    )
    popd
)

Я запустил это решение как файл .bat, поэтому я использовал %% вместо %.

%%n = имя (также известное как C:\Directory\Name)
%%p = проект (также известное как C:\Directory\Name\Project)
%%f = файл для перемещения (рекурсивный просмотр папок и перенос их на уровень проекта)

В конечном счете, мне не удалось заставить @dbenham удалить пустые папки, поэтому я использовал эту утилиту: http://www.jonasjohn.de/red.htm. Пока это кажется довольно интуитивным и как будто решает проблему без особых усилий с моей стороны :)

Спасибо за помощь всем!

person KingOfTheNerds    schedule 18.12.2014