Как переместить файлы в уже существующие папки, основываясь на том, какое имя папки содержится в каждом имени файла? - PullRequest
0 голосов
/ 26 сентября 2019

У меня уже создано много папок, состоящих только из (7) цифровых символов.Папки находятся в том же родительском каталоге, что и файлы для перемещения.Формат имени файла может содержать одно из имен папок в начале с последующим пробелом или подчеркиванием.Возможно, могут быть имена файлов, у которых нет соответствующей папки, и в этом случае перед перемещением файла потребуется создать папку.В этом случае я хотел бы добавить подтверждение, прежде чем продолжить.Имена файлов без пробелов и подчеркиваний должны остаться.

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

FOR /F "delims= eol=" %%A IN ('dir /B /A-D "*.*"') DO (
    FOR /F "tokens=1 delims=_" %%B IN ("%%A") DO (
        SET "token_1=%%B"
        SET "num_test=!token_1:~-1!"
        SET "foldername=!token_1!"
        MD "!foldername!\" >nul 2>&1
        MOVE "%%~fA" "!foldername!\"
    )
)

Выше приведена попытка исходного кода, однако, ищем более простой подход с подтверждениемДобавлено: Какой пакетный код может быть использован для упрощения вышесказанного, если предположить, что формат имени папки состоит из (7) числовых символов?

Ниже приведено то, что я с тех пор скомпилировал.

@ECHO OFF
FOR /F "eol=| delims=" %%I IN ('dir "???????" /AD-H /B 2^>nul ^| findstr /R /X "......."') DO MOVE /Y "%%I*" "%%I" >nul 2>nul
:choice
set /P c=Files remain, create new folders for these files[Y/N]?
if /I "%c%" EQU "Y" goto :somewhere
if /I "%c%" EQU "N" goto :somewhere_else
goto :choice
:somewhere
@For /F "EOL=_Tokens=1*Delims=_" %%A In ('Dir /B/A-D "*_*" 2^>NUL^|FindStr "^[0-9]*_[^_]"')Do @RoboCopy . "%%A" "%%A_%%B" /Mov>NUL 2>&1
FOR /F "eol=| delims=" %%I IN ('dir "???????" /AD-H /B 2^>nul ^| findstr /R /X "......."') DO MOVE /Y "%%I*" "%%I" >nul 2>nul
Exit
:somewhere_else
exit

Ответы [ 2 ]

0 голосов
/ 26 сентября 2019

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

:

@For /F "EOL=_Tokens=1*Delims=_" %%A In ('Where ".:???????_*.*" 2^>NUL^|FindStr "^[0-9]*_[^_]"')Do @RoboCopy . "%%A" "%%A_%%B" /Mov>NUL 2>&1

:

For /F "EOL=_Tokens=1*Delims=_" %A In ('Where ".:???????_*.*" 2^>NUL^|FindStr "^[0-9]*_[^_]"')Do RoboCopy . "%%A" "%%A_%%B" /Mov>NUL 2>&1

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

0 голосов
/ 26 сентября 2019

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

for /D %%I in (*) do move /Y "*%%I*" "%%I\" >nul 2>nul

FOR ищет в текущем каталоге не скрытые каталоги, соответствующие шаблону подстановки * (любое имя каталога), и запускает команду MOVE , где исходная строка является шаблоном подстановкисопоставление всех файлов с текущим именем каталога в любом месте имени файла.

Стандартный вывод с перечислением перемещенных файлов и общего количества перемещенных файлов подавляется путем перенаправления его с STDOUT на устройство NUL .

Вывод сообщения об ошибке в случае отсутствия файла для перемещения или невозможности перемещения одного из файлов (например, при открытии в приложении) перенаправляется из STDERR на устройство NUL для его подавления.

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

for /D %%I in (????) do move /Y "*%%I*" "%%I\" >nul 2>nul

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

for /D %%I in (????) do move /Y "*_%%I_*" "%%I\" >nul 2>nul

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

for /D %%I in ("%~dp0????") do move /Y "%~dp0*_%%~nxI_*" "%%I\" >nul 2>nul

%~dp0 ссылается на диск и путь аргумента 0 пакетного файла.Аргумент 0 обработанного пакетного файла всегда является самим пакетным файлом.Таким образом, %~dp0 ссылается на диск и путь к пакетному файлу, который всегда заканчивается обратной косой чертой и поэтому не следует использовать дополнительную обратную косую черту при объединении %~dp0 с именами файлов / папок или шаблонами подстановочных знаков.

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

for /D %%I in ("C:\Temp\Folder1\*") do move /Y "C:\Temp\Folder2\%%~nxI_*" "%%I\" >nul 2>nul

Обновление:

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

for /F "eol=| delims=" %%I in ('dir "%~dp0Folder1\???????" /AD-H /B 2^>nul ^| %SystemRoot%\System32\findstr.exe /R /X "......."') do move /Y "%~dp0Folder2\%%%I_*" "%~dp0Folder1\%%I\" >nul 2>nul

Команда FOR запускается в фоновом режиме еще один командный процесс с %ComSpec% /c иуказанная командная строка.

Операторы перенаправления > и | необходимо экранировать с помощью символа вставки ^ в FOR , чтобы интерпретировать командную строку как буквенные символы при обработке интерпретатора команд Windowsэта командная строка перед выполнением команды FOR , которая выполняет встроенную командную строку в отдельном командном процессе, запущенном в фоновом режиме.

В фоновом командном процессе сначала выполняется команда DIR с поиском не скрытых каталогов длиной от одного до семи символов и выводом только совпадающих имен каталогов.

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

FOR захватывает этот вывод для обработки STDOUT запущенного фонового командного процесса и обрабатывает эти строки после того, как запущенный cmd.exe завершил себя.

FOR с параметром /F игнорирует пустые строки, которые в этом случае не встречаются.По умолчанию он также игнорирует строки, начинающиеся с ;.Имя каталога может начинаться с точки с запятой, но оно не может содержать |.По этой причине eol=| переопределяет символ конца строки на вертикальную черту, чтобы не игнорировать любое имя каталога.Захваченная строка будет также разделена на горизонтальные табуляции и обычные пробелы, и только первая разделенная табуляцией / пробелом подстрока будет присвоена переменной цикла I.Это поведение разделения строк полностью отключается с помощью delims= в конце строки параметров, которая определяет пустой список разделителей строк.

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

[0-9][0-9][0-9][0-9][0-9][0-9][0-9]
[0123456789][0123456789][0123456789][0123456789][0123456789][0123456789][0123456789]

Имя каталога должно содержать ровно семь из этих символов 0123456789¹²³ при использовании первой строки поиска регулярного выражения.То, что диапазон символов 0-9 включает также ¹²³, является FINDSTR специальным.Насколько я знаю, никакой другой исполняемый файл, поддерживающий регулярные выражения, не делает этого.Вторая строка поиска регулярного выражения соответствует только именам каталогов, состоящим ровно из семи цифр.

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

  • call /? ... для объяснения %~dp0.
  • dir /?
  • findstr /?
  • for /?
  • move /?

См. Также статью Microsoft о Использование операторов перенаправления команд .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...