Настоящий быстрый и непроверенный
@ECHO OFF
SETLOCAL
SET "sourcedir="whatever my directory name is"
PUSHD %sourcedir%
FOR /f "tokens=1,2,3,4,5,* delims=_" %%a IN (
'dir /b /a-d "*_*-*-*-*_*_*_*.*"'
) DO (
echo ++%%a++%%b++%%c++%%d++%%e++%%f++
MD %%b_%%c_%%d_%%e 2>nul
MOVE "%%a_%%b_%%c_%%d_%%e_%%f" "%%b_%%c_%%d_%%e"
)
POPD
GOTO :EOF
Вы были очень близки - строка echo
должна показать вам, как имя файла разбирается на %%a
.. %%f
. Части разделены ++
, который является очень очевидным разделителем и показывает, есть ли пробелы в каком-либо элементе.
Добавление *
в список токенов означает «все, что находится за номером, указанным выше». Затем воссоздайте имя файла из частей - строка вместе, начиная с %%a
, заново вставив все подчеркивания.
Это также должно работать:
@ECHO OFF
SETLOCAL
SET "sourcedir="whatever my directory name is"
PUSHD %sourcedir%
FOR /f %%q IN (
'dir /b /a-d "*_*-*-*-*_*_*_*.*"'
) do (
FOR /f "tokens=1,2,3,4,5,* delims=_" %%a IN ("%%q") do
echo ++%%a++%%b++%%c++%%d++%%e++%%f++FROM++%%q++
MD %%b_%%c_%%d_%%e 2>nul
MOVE "%%q" "%%b_%%c_%%d_%%e"
)
)
POPD
GOTO :EOF
В этой версии %%q
получает каждое имя файла по очереди, затем "%%q"
может быть проанализировано с помощью for /f
, а исходное имя файла остается без изменений в %%q
, готовом для использования в операторе move
.
[на самом деле, довольно незначительный] Редакция:
REM <!-- language: lang-dos -->
@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
PUSHD "%sourcedir%"
FOR /f "tokens=1,2,3,4,5,* delims=_" %%a IN (
'dir /b /a-d "*_*-*-*-*_*_*_*.*"'
) DO IF EXIST "%%a_%%b_%%c_%%d_%%e_%%f" (
MD %%b_%%c_%%d_%%e 2>nul
MOVE "*%%b_%%c*" "%%b_%%c_%%d_%%e"
)
POPD
SET "sourcedir=U:\sourcedir\t h r e e"
PUSHD "%sourcedir%"
FOR /f %%q IN (
'dir /b /a-d "*_*-*-*-*_*_*_*.*"'
) do IF EXIST "%%q" (
FOR /f "tokens=1,2,3,4,5 delims=_" %%a IN ("%%q") DO (
MD %%b_%%c_%%d_%%e 2>nul
MOVE "*%%b_%%c*" "%%b_%%c_%%d_%%e"
)
)
POPD
GOTO :EOF
Да - неправильно прочитано, что вы хотели переместить все файлы, содержащие - играли всю ночь ...
Вышеуказанная партия состоит из двух частей: первая с использованием %%a
.. %%f
и вторая с %%q
.
Сложность заключается в том, что move *[pattern]*
будет перемещать все файлы, как требуется, НО for /f...'dir...
создает список ВСЕХ соответствующих файлов, которые были изначально в каталоге.
После обработки первого имени файла другие файлы, содержащие 01-PG-18-1000_NC
, будут перемещены, поэтому вы получите сообщение об ошибке «файлы не найдены» для следующего 01-PG-18-1000_NC
файла в списке, который for
имеет встроенный.
Конечно, можно собрать вместе некоторый механизм, гарантирующий, что шаблон 01-PG-18-1000_NC
будет обработан только один раз, но простой if exists
для полного имени файла, возвращаемого for...%%a...
и перестроенного, может использоваться для управления MD/MOVE
команды в виде файла больше не будут существовать при обработке следующего 01-PG-18-1000_NC
(так как он уже был перемещен). Намного проще, если использовать метод %%q
.
Конечно, вы также можете просто избавиться от сообщений об ошибках вместо установки шлюза - но это, вероятно, считается грубым.
Также предложение aschipfl о добавлении delims=
к for...%%q...
вполне допустимо, если у вас есть разделители, такие как Пробел в ваших именах файлов (и ничего не стоит, независимо от того)
О - и я пропустил (
в части do
в моем первоначальном ответе - всегда происходит, когда вы на самом деле не тестируете код, особенно когда вы устали.