Создайте папки из шаблона имени файла и переместите файлы в эти папки
Я хочу создать командный файл / команду 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 и выбирает последний из них.