Пакетный файл для удаления определенных подпапок, но сначала перемещения всего внутри них наружу

Я ищу помощь с пакетным скриптом, который может помочь мне удалить определенные подпапки из всех каталогов, которые находятся в том же месте, что и пакетный файл. Но вместо того, чтобы удалять все в подкаталоге, я хочу сначала переместить содержимое за пределы подкаталога.

Чтобы уточнить, я получаю файлы, которые всегда вложены в папки с очень специфическим шаблоном:

  • Каждый запрос, который я получаю, находится в папке с уникальным именем, которая не соответствует определенному шаблону (папка заданий).
  • Внутри каждой папки заданий есть две вещи:
    1. Папка, обозначающая язык, на котором находится файл (Lang Folder).
    2. XML-файл с именем «Manifest.xml», содержащий инструкции и метаданные.
  • Внутри каждой папки Lang есть папка, обозначающая марку файла (Brand Folder).
  • Внутри каждой папки Brand находится случайный набор подпапок, содержащих файлы JSON с различной степенью вложенности внутри разных подпапок.

Таким образом, типичный запрос будет содержать следующую структуру: Папка задания/папка Lang/папка бренда/...

И я хочу преобразовать все папки в соответствии с этой структурой: Папка с заданиями/папка с брендом/...

Ниже вы можете увидеть пример того, как сейчас выглядит структура папок и как я хотел бы, чтобы она выглядела в конце.

Структура папок и файлов перед запуском командного файла:

  • French_Job1373
    • Французский
      • БрендA
        • Подпапка
          • Пример.json
    • Манифест.xml
  • German_Job1374
    • Немецкий
      • МаркаB
        • Подпапка1
          • Подпапка2
            • Подпапка3
              • ПримерФайл.json
    • Манифест.xml
  • Японский_Job1375
    • Японский
      • БрендC
        • Подпапка1
          • Пример.json
    • Манифест.xml
  • Korean_Job1376
    • Корейский
      • БрендC
        • Подпапка1
          • Подпапка13
            • ПримерSrc.json
    • Манифест.xml

Структура папок и файлов, какой она должна быть после запуска батника:

  • French_Job1373
    • БрендA
      • Подпапка
        • Пример.json
    • Манифест.xml
  • German_Job1374
    • МаркаB
      • Подпапка1
        • Подпапка2
          • Подпапка3
            • ПримерФайл.json
    • Манифест.xml
  • Японский_Job1375
    • БрендC
      • Подпапка1
        • Пример.json
    • Манифест.xml
  • Korean_Job1376
    • БрендC
      • Подпапка1
        • Подпапка13
          • ПримерSrc.json
    • Манифест.xml

Я хотел бы иметь пакетный файл, который по существу удаляет папку Lang, извлекая все из папки Lang на один уровень вверх.

Следует принять во внимание следующее:

  • Файл Manifest.xml трогать не следует. Он должен оставаться на уровне папки заданий.
  • Все с уровня папки бренда, включая саму папку бренда, следует переместить на один уровень вверх (на тот же уровень, где находится файл Manifest.xml).
  • Языковая папка (которая на данный момент должна быть пустой) должна быть удалена.
  • Существует конечный список возможных языков, в честь которых названа папка Lang. Если требуется указать все возможные языки в пакетном файле, я хотел бы иметь возможность добавлять новые языки в список в будущем.

До сих пор мне удавалось заставить приведенный ниже пакетный файл работать должным образом, но мне нужно запускать столько раз, сколько есть папок заданий, и я должен поместить его в языковую папку, чтобы он работал должным образом. Если я помещу его в другое место, он просто удалит папку Lang со всем ее содержимым и ничего не переместит. Я хочу, чтобы пакетный файл проверял все папки, которые находятся рядом с ним, и выполнял операцию столько раз, сколько необходимо.

Что у меня есть до сих пор:

@echo off
if -%1==- echo No parameters! You must add %%P parameter! & pause & goto :EOF
cd /d %1
move * ..
for /d %%f in (*) do move %%f ..
cd ..
"%commander_path%\totalcmd.exe" /o /s %1\..
rd %1
FOR /d /r . %%d IN (Russian) DO @IF EXIST "%%d" rd /s /q "%%d"
FOR /d /r . %%d IN (French) DO @IF EXIST "%%d" rd /s /q "%%d"
FOR /d /r . %%d IN (German) DO @IF EXIST "%%d" rd /s /q "%%d"
FOR /d /r . %%d IN (Japanese) DO @IF EXIST "%%d" rd /s /q "%%d"
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
313
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это отличное описание задачи перемещения папки, которую можно выполнить с помощью пакетного файла, хранящегося в папке, содержащей все папки заданий, содержащие следующие строки.

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "ErrorPause = "
for /D %%I in ("%~dp0*_Job*") do for /F "eol=| delims=_" %%J in ("%%~nxI") do if exist "%%I\%%J\" (
    for /F "eol=| delims = " %%K in ('dir "%%I\%%J" /A /B 2^>nul') do move "%%I\%%J\%%K" "%%I\" 2>nul || (echo Failed to move:   "%%I\%%J\%%K"& set "ErrorPause=1")
    rd "%%I\%%J" 2>nul || (echo Failed to delete: "%%I\%%J"& set "ErrorPause=1")
)
if defined ErrorPause pause
endlocal

Первый цикл FOR ищет в папке пакетного файла, на которую ссылается %~dp0 (путь всегда заканчивается обратной косой чертой), нескрытые подпапки, соответствующие шаблону подстановки *_Job*. Таким образом, переменной цикла I присваиваются одно за другим полные имена папок папок заданий French_Job1373, German_Job1374, German_Job1374, Korean_Job1376, ...

Вторая команда FOR разделяет текущее имя папки заданий на символы подчеркивания, при этом все до первого подчеркивания назначается переменной цикла J. Это имя папки Lang в текущей папке заданий.

Условие IF проверяет, существует ли вообще папка Lang в текущей папке заданий, поскольку в противном случае для текущей папки заданий делать нечего.

Третий цикл FOR запускает еще один командный процесс в фоновом режиме с добавлением %ComSpec% /c и командной строки внутри ' в качестве дополнительных аргументов. Таким образом, выполняется с установленной Windows в C:\Windows и путем к пакетному файлу C:\Temp, например, для первой папки Lang первой папки заданий:

C:\Windows\System32\cmd.exe /c dir "C:\Temp\French_Job1373\French" /A /B 2>nul

Команда DIR выводит

  • все имена папок и файлов, включая скрытые из-за опции /A (все атрибуты)
  • в голом формате из-за опции /B, что означает просто имя папки/файла без пути
  • в указанном каталоге.

FOR игнорирует папки и файлы со скрытым набором атрибутов, что является причиной использования командной строки DIR, выполняемой отдельным командным процессом в фоновом режиме.

Прочтите документацию Microsoft о Использование операторов перенаправления команд для объяснения 2>nul. Оператор перенаправления > должен быть экранирован символом вставки ^ в командной строке FOR, чтобы он интерпретировался как буквальный символ, когда интерпретатор команд Windows обрабатывает эту командную строку перед выполнением команды FOR, которая выполняет встроенную командную строку dir с использованием отдельного командного процесса, запущенного в фоновом режиме.

FOR с опцией /F по умолчанию будет разделять все строки, захваченные из дескриптора STDOUT фонового командного процесса после запуска cmd.exe, завершится на подстроки, используя обычный пробел и горизонтальную табуляцию в качестве разделителей строк, будет игнорировать следующую строку, если первая подстрока начинается с точки с запятой. символ конца строки по умолчанию, и в противном случае назначит только первую строку, разделенную пробелом / табуляцией, для указанной переменной цикла K. Такое поведение не будет проблемой в соответствии с примером для папок BrandA, BrandB и два раза BrandC. Но использование строки параметров "eol=| delims = " приводит к использованию вертикальной черты в качестве символа конца строки, который не может содержать имя папки/файла, и определению пустого списка разделителей строк, который отключает поведение разделения строк. Таким образом, каждое имя папки/файла, выводимое DIR без пути, полностью назначается переменной цикла K одно за другим.

Команда MOVE перемещает текущую папку/файл в папке Lang текущей папки заданий на один уровень вверх в папку заданий. Это действие выполняется очень быстро, так как оно выполняется путем простого обновления основной таблицы файлов файловой системы, которая кэшируется Windows. Существует вывод сообщения об ошибке, и переменная среды ErrorPause определяется, если возникает ошибка при перемещении папки или файла на один уровень выше.

Текущая папка Lang удаляется с помощью команды RD после того, как все папки и файлы в текущей папке Lang будут успешно перемещены. Удаление папки завершается сбоем, если папку или файл в папке Lang нельзя переместить вверх из-за того, что файл в этом дереве папок в данный момент открыт приложением, или папка в этом дереве папок является текущей папкой любого запущенного процесса, или папка/файл с таким именем уже существует в папке заданий. Выводится сообщение об ошибке, и переменная среды ErrorPause определяется при сбое удаления папки Lang, поскольку папка не пуста.

Команда PAUSE останавливает выполнение пакетного файла до тех пор, пока не будет нажата клавиша, если произошла ошибка. В противном случае обработка пакетного файла завершается без каких-либо дальнейших действий пользователя.

Пакетный файл можно просто запустить еще раз в случае ошибки из-за того, что файл открыт в приложении, или папка является текущей папкой запущенного процесса, или папка/файл для перемещения уже существует в папке заданий после закрытия файл в приложении или само приложение соответственно удаление папки/файла в папке заданий.

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

  • call /? ... объясняет %~dp0 ... диск и путь аргумента 0, который является путем командного файла.
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • if /?
  • move /?
  • pause /?
  • rd /?
  • set /?
  • setlocal /?

Все эти команды являются внутренними командами командного процессора Windows cmd.exe.

См. также: Одна строка с несколькими командами с использованием пакетного файла Windows

Другие вопросы по теме