Я пытался выяснить, как создать команду dos, которая может "видеть" часть имени файла, затем создать папку и отсортировать каждый файл, в котором есть эта часть имени файла.

Каждое имя файла имеет следующие символы (исключая расширение):

3 буквы, 5 цифр, 1 буква, 1 цифра

Например: BBB12345B0

Каждая буква и число в имени файла могут отличаться, но имя файла всегда будет иметь одинаковую сборку.

Сценарий должен распознать только 5 цифр, затем создать папку из этих 5 цифр и затем переместить эти файлы в эту папку.

Следующее я нашел в интернете:

@echo off
for /f "delims=" %%a in ('dir /b /a-d') do (

if not "%%~fa"=="%~f0" (

md "%%~na" 2>nul

if exist "%%a" move "%%~na.*" "%%~na"

)

)

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

Я пытался работать с "токенами" в этом сценарии. Также используются некоторые другие методы, но ни один из них не работает должным образом. Я также не очень знаком с такого рода пакетными сценариями. Кто-нибудь может мне с этим помочь?

4 ответа4

0

Привет JdeBP и Мартин,

Я пробовал оба решения, данные JdeBP, но я получаю ошибку "файл не ожидается". Вариант powershell от Martin выглядит хорошим вариантом. Я посмотрю дальше, если этот вид пакетного скриптинга, если я должен использовать его более

0

Перед ответом с CMD-сценариями для изменения, вот другой способ, использующий TCC /LE от JP Software, альтернативный интерпретатор команд:

@echo off
for %file in ([a-z][a-z][a-z][0-9][0-9][0-9][0-9][0-9][a-z][0-9].*) do ( 
    mkdir 2>NUL "%@instr[3,5,%file%]"
    ren "%file%" "%@instr[3,5,%file%]\%file%"
)

Обратите внимание, что довольно длинный подстановочный знак соответствует вашей спецификации и не будет включать имена файлов с различными шаблонами букв и цифр. Менее строгим подстановочным знаком может быть [?][?][?][?][?][?][?][?][?][?].* , Который соответствует каждому имени файла длиной ровно 10 символов, без расширения. Также обратите внимание, что нет необходимости явно указывать /a:-d с for , поскольку исключение каталогов уже используется по умолчанию.

Используйте параметр /n для команды ren чтобы отобразить, что произойдет без перемещения файлов.

Между прочим, безумие разбирать вывод dir /b с for . Даже в CMD от Microsoft for поиска используется сам подстановочный знак.

дальнейшее чтение

  • ЗА Справочник по командам TCC/LE. JP Software.
  • @INSTR. Справочник по командам TCC/LE. JP Software.
0

В PowerShell:

$files = gci . | where {!$_.psIsContainer}
foreach ($file in $files) {
    $dir = $file.Name.Substring(3, 5)
    if (!(test-path -path $dir)) {
        mkdir $dir
    }
    mv $file $dir
}

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

0

Если это возможно, вам следует вместо этого переключиться на PowerShell, он может быть установлен на WinXP и включен по умолчанию в Windows Vista и выше, поэтому не нужно ничего устанавливать. Он имеет много инструментов, которые делают множество задач, которые бесполезны в пакетном режиме, действительно просты. И это также позволяет вам использовать com-объекты и библиотеку .net в крайнем случае.

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

Есть много хороших учебников, если вы ищете в Интернете "учебник powershell" и т.д.

(Если у меня будет время позже, я сделаю простой скрипт, который выполнит ту задачу, которая вам нужна.)

Редактировать: Кроме того, это гораздо более читабельным, чем пакет ^^

Edit2: короткий скрипт, который делает то, что вам нужно:

$dir="X:\Your\Path";

get-childitem $dir | %{

    $file=$_;
    if(-not $file.PSIsContainer)
    {
        if($file.PSChildName -match "^.*(\w{3})(\d{5})(\w{1})(\d{1}).*$")
        {
            $folder = "$($file.PSParentPath)\$($matches[2])";

            if(test-path $folder)
            {
                Move-Item "$($file.PSPath)" "$folder\$($file.PSChildName)";
            }
            else
            {
                mkdir $folder;
                Move-Item "$($file.PSPath)" "$folder\$($file.PSChildName)";
            }
        }
    }
}

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .