Пакетный скрипт для создания папки на основе имени, добавления к существующему коду - PullRequest
1 голос
/ 21 января 2012

Код ниже работает отлично, вот список его функций:

  1. Перемещает файлы, основанные на первых 4 символах, в предварительно созданную папку с теми же первыми 4 символами
  2. Если папка не существует, файл не будет перемещен, так как нет папки с тем же кулаком 4 символа.

    @echo on
    setlocal enabledelayedexpansion
    cls
    
    pushd R:\Contracts\Sites
    
    for /f "tokens=*" %%1 in ('dir /a-d /b *') do (
        set filename=%%1&set dirname=!filename:~0,4!
    
        for /f "tokens=*" %%A in ('dir /ad /b') do (
             set dirid=%%A & set dirid=!dirid:~0,4!
    
             if "!dirid!" equ "!dirname!" move %%1 %%A
        )        
    )
    

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

У меня есть 5 файлов

  • X32A-test.docx или X32A-test.pptx (будет только один docx или pptx, "НИКОГДА два с одним и тем же именем ")
  • X32A-test.pdf
  • X32A-test.avi
  • X32A-test-eng.sub
  • X32A-test-small.jpg

Я хотел бы, чтобы код СОЗДАЛ папку, если она не существует, на основе имени файла, если оно имеет расширение docx или pptx.

Таким образом, в приведенном выше примере будет создана папка с именем: "X32A-test".Затем все остальные файлы с «X32A» в начале названия будут перемещены в эту вновь созданную папку «X32A-test».

Надеюсь, это достаточно ясно.Если нет, пожалуйста, спросите меня для получения дополнительной информации.

Спасибо

Ответы [ 3 ]

2 голосов
/ 21 января 2012

Гораздо проще и эффективнее использовать простой FOR вместо FOR / F в вашем случае.

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

Первый цикл находит файлы .pptx и .docx и создает необходимые папки

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

@echo on
setlocal enableDelayedExpansion
cls

pushd R:\Contracts\Sites

for %%F in (*.docx *.pptx) do (
  set "folder=%%F"
  2>nul md !folder:~0,4!
)
for /d %%F in (*) do move %%F* %%F
popd

При необходимости вы можете защитить себя от имен каталогов короче длины 4.

@echo on
setlocal enableDelayedExpansion
cls

pushd R:\Contracts\Sites

for %%F in (*.docx *.pptx) do (
  set "folder=%%F"
  set folder=!folder:~0,4!
  if !folder:~0,3! neq !folder! 2>nul md !folder!
)
for /d %%F in (????) do (
  set "folder=%%F"
  if "!folder:~0,3!" neq "%%F" move %%F* %%F
)
popd

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

1 голос
/ 21 января 2012

Я вижу весь процесс (включая уже реализованную часть) следующим образом:

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

  2. Для всех оставшихся файлов .docx и .pptx создайте каталоги на основе имен файлов.

  3. Очевидно, что шаг № 2 создаетновые "дома", и они все еще будут "необитаемыми" так далеко.Итак, все, что осталось сделать сейчас, это повторить шаг № 1.

Поэтому я бы, вероятно, реорганизовал ваш процесс и, с дополнительным требованием, мог бы быть реализован следующим образом:

…

PUSHD <i>your_root_directory</i>

FOR /D %%D IN (*) DO (
  CALL :movefiles "%%D"
)

FOR %%F in (*.docx *.pptx) DO (
  MKDIR "%%~dpnF"
  CALL :movefiles "%%~dpnF"
)

…

GOTO :EOF

:movefiles
SET "dirname=%~n1"
SET "mask=%dirname:~0,4%*"
MOVE "%~dp1%mask%" %1

Примечание. Шаги № 2 и № 3 могут быть реализованы как отдельные циклы или объединены в один.В приведенном выше сценарии используется последний подход.

1 голос
/ 21 января 2012

Вы можете использовать отрицательные смещения в оценке !var:~offset,len! следующим образом:

set fspec=X32A-test.docx
echo !fspec:~-10!
echo !fspec:~0,-10!

Эта вторая строка выше дает вам -test.docx, и вы можете просто сравнить это с вашими двумя желаемыми возможностями с помощью оператора if (или двух).

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

Следующий пример сценария показывает, как это можно сделать:

@setlocal enableextensions enabledelayedexpansion
@echo off
set fspec=X32A-test.docx
set bit1=!fspec:~-10!
set bit2=!fspec:~0,-10!
if .!bit1!.==.-test.docx. echo mkdir !bit2!
if .!bit1!.==.-test.pptx. echo mkdir !bit2!
endlocal

Я повторяю команду mkdir, а не выполняю ее, поэтому вам нужно убрать echo. Вам также нужно будет интегрировать операторы set и if в ваш цикл, но, исходя из того, что у вас есть, у вас не должно возникнуть никаких проблем с этим.


Если, как вы, кажется, указываете в комментарии, первые четыре символа являются ключом, а последние пять решают, создавать ли каталог, как в:

x32s-test.docx
a21w-production.pptx
xxxx-whatever_the_blazes_you_want.some_other_rubbish.docx

Тогда вас действительно интересуют только первые четыре и последние пять:

@setlocal enableextensions enabledelayedexpansion
@echo off
set fspec=a12b-whatever_the_blazes_you_want.some_other_rubbish.docx
set bit1=!fspec:~-5!
set bit2=!fspec:~0,4!
if .!bit1!.==..docx. echo mkdir !bit2!
if .!bit1!.==..pptx. echo mkdir !bit2!
endlocal

Проверяет правильные расширения и выходы:

mkdir a12b

как и ожидалось.

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