Создайте папки из шаблона имени файла и переместите файлы в эти папки

Я хочу создать командный файл / команду Windows для следующего сценария:

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

Например:

Это имена файлов:
1. ABCD-33-21234-4652_00-2017-03.txt
2. SECA-11-4652_00-2017-03.txt
3. 8888-asde0-dswc-33-4444_55-2016-05.txt

Мне нужно переместить эти файлы в каталоги (создать их, если они не существуют) с именами XXXX_XX

так что в основном мне нужно переместить их в папки как:

....\ 4652_00 \ ABCD-33-21234-4652_00-2017-03.txt
....\ 4652_00 \ SECA-11-4652_00-2017-03.txt
....\ 4444_55 \8888-asde0-dswc-33-4444_55-2016-05.txt

Я много пробовал, но не смог найти решение. Ценю твою помощь.

2 ответа

Вот решение для строки cmd, обертывающее один слой PowerShell.
Используется в партии, %знак должен быть удвоен %%,

Пример вывода на мой оперативный диск A:

> tree /F
A:.
    8888-asde0-dswc-33-4444_55-2016-05.txt
    ABCD-33-21234-4652_00-2017-03.txt
    SECA-11-4652_00-2017-03.txt

powershell -NoP -C "dir *.txt|where {$_.BaseName -match '-(\d{4}_\d{2})-20'}|%{MD $matches[1] -EA 0;$_|Move -Dest {$matches[1]}}"

> tree /F
A:.
├───4444_55
│       8888-asde0-dswc-33-4444_55-2016-05.txt
└───4652_00
        ABCD-33-21234-4652_00-2017-03.txt
        SECA-11-4652_00-2017-03.txt

Основным является регулярное выражение -(\d{4}_\d{2})-20 который соответствует шаблону -xxxx_xx-20 и круглые скобки (xxxx_xx) отмечают интересующую нас группу.

Более подробная версия без псевдонимов скрипта PowerShell:

Get-ChildItem *.txt |
  Where-Object BaseName -Match  '-(\d{4}_\d{2})-20'|
    ForEach-Object {
      mkdir $matches[1] -ErrorAction SilentlyContinue
      $_ | Move-Item -Destination {$matches[1]}
    }
@ECHO Off
SETLOCAL enabledelayedexpansion
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
FOR /f "delims=" %%a IN (
 'dir /b /a-d "%sourcedir%\*-????_??-*.txt" '
 ) DO (
 SET "filename=%%a"
 SET "filename=!filename:-= !"
 SET "moved="
 FOR %%b IN (!filename!) DO IF NOT DEFINED moved (
  FOR /f "tokens=1*delims=_" %%p IN ("%%b") DO IF "%%q" neq "" (
   ECHO MD "%destdir%\%%p_%%q" 2>NUL
   ECHO MOVE "%sourcedir%\%%a" "%destdir%\%%p_%%q\"
   SET "moved=Y"
  )
 )
)

GOTO :EOF

Вам нужно будет изменить настройки sourcedir а также destdir в соответствии с вашими обстоятельствами.

Требуемые MD команды просто ECHOЭд для тестирования. После проверки правильности команд измените ECHO(MD в MD на самом деле создавать каталоги. присоединять 2>nul подавить сообщения об ошибках (например, когда каталог уже существует)

Требуемые команды MOVE просто ECHOЭд для тестирования. После проверки правильности команд измените ECHO(MOVE в MOVE на самом деле переместить файлы. присоединять >nul подавить сообщения отчета (например, 1 file moved)

dir Команда возвращает каждое имя файла, соответствующее маске %%aотсюда filename,

каждый - в filename затем заменяется пробелом и for..%%b обрабатывать имя файла как список разделенных пробелами строк.

Каждая строка в %%b токенизируется, и первая строка соответствует строке_строка присваивается %%p а также %%q, Если %%q не пусто, то мы нашли строку_строку, так что md а также move и установить moved флаг, чтобы гарантировать, что дальнейшие найденные совпадения будут проигнорированы.

Обратите внимание, что это не будет иметь дело с ситуацией, когда у вас есть имя файла вроде -abc_d-EFGH_JK- что-то - это предполагает, что требуемое назначение - это первое появление строки_string, которая в этом случае будет abc_dне EFGH_JK, Это легко исправить, если требуется.


Пересмотр в свете исправления структуры файла (без подчеркивания - только тире)

@ECHO Off
SETLOCAL enabledelayedexpansion
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
FOR /f "delims=" %%a IN (
 'dir /b /a-d "%sourcedir%\????-*-????-??-*.txt" '
 ) DO (
 SET "filename=%%a"
 CALL :newname !filename:-= !

 IF DEFINED newdir (
  ECHO MD "!newdir!" 2>NUL
  ECHO MOVE "%sourcedir%\%%a" "%destdir%\!newdir!\"
 )
)

GOTO :EOF

:newname
IF "%5" neq "" shift&GOTO newname
SET "newdir=%1-%2"
IF "%newdir:~4,1%" equ "-" IF "%newdir:~7%" equ "" IF "%newdir:~6,1%" neq "" GOTO :EOF
SET "newdir="
GOTO :eof

Новый код ищет последовательность -???? -?? -string-string и выбирает последний из них.

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