Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   Перемещение файлов в папки с аналогичными именами (http://forum.oszone.net/showthread.php?t=325084)

londondron 21-03-2017 13:49 2721706

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

cls
chcp 1251
@echo off
set "tr=C:\Users\VML\OneDrive\Приказы" - это я упрощаю использование пути
for %%a in ("%tr%"\*.jpg) do (                - перебор файлов jpeg
        set "fn=%%a"                                  - присваиваю новой переменной значение переменной из for, чтобы из нее м.б. извлечь фамилию
        set "sn=%%fn:%tr%=%%"              - первым делом пытаюсь удалить путь к файлу, чтобы осталось только его имя, НО ЗДЕСЬ в итоге ничего и не получается
        echo %sn%
)
set tr=                                                      - удаляю использованные переменные
set sn=
set fn=

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

Iska 21-03-2017 14:32 2721719

Цитата:

Цитата londondron
используя часть имени файла (а именно фамилию человека) »

Какую часть? Как выглядят имена файлов, как в них определить, что вот эта часть — фамилия?

Цитата:

Цитата londondron
находить уже существующую папку »

Где находить?

londondron 21-03-2017 14:45 2721725

файлы имеют такой формат: "Фамилия_Прием.jpg"
Папки с фамилиями расположены в папке: "C:\Users\VML\OneDrive\ЛИЧНЫЕ ДЕЛА\" и имеют формат "00-00-00 Фамилия".

megaloman 21-03-2017 19:36 2721815

londondron,
1. как понять слово Прием в имени файла? Оно неизменно присутствует в каждом имени или это некое слово, которое индивидуально для каждого файла?
2. В имени файла только один символ подчёркивания?
3. А в папке, куда перемещаем файл, не может быть такого же более раннего?
4. А однофамильцы учитываются?
5. А если папки нет, её создавать? А что такое 00-00-00?

megaloman 21-03-2017 20:40 2721830

londondron,Вот код по Вашему заданию.
1. Файлы называются *_Прием.jpg Фамилия отделяется символом _ подчёркивания. В фамилии не может быть _
2. Если в выходной папке уже присутствует файл с совпадающим именем, файл не перемещается
3. Если папки нет, файл не перемещается.
Как описАли, так и сделано :)
Код:

@Echo Off

chcp 1251 >nul

Set "BoxIn=Z:\Users\VML\OneDrive\Приказы"
Set "MaskIn=*_Прием.jpg"

Set "BoxOut=Z:\Users\VML\OneDrive\ЛИЧНЫЕ ДЕЛА"
Set "MaskOut=??-??-?? "

FOR /F "usebackq delims=" %%f IN (`Dir "%BoxIn%\%MaskIn%" /B /A:-D 2^>nul`) DO (
        FOR /F "tokens=1 delims=_" %%i IN ("%%f") DO (
                FOR /F "usebackq delims=" %%d IN (`Dir "%BoxOut%\%MaskOut%%%i" /B /A:D 2^>nul`) DO (
                        Move "%BoxIn%\%%f" "%BoxOut%\%%d\" >nul
                )
        )
)


londondron 22-03-2017 06:44 2721946

Спасибо!
Все именно так, как Вы написали в последнем посте.
Сейчас буду пробовать и разбираться. Потом отпишусь.

londondron 22-03-2017 07:43 2721949

Я понял: Вы разбили каждую строку первого вывода команды DIR на подстроки во втором цикле и получили фамилии, которые в 3-м цикле подставили к маске папок, предназначенных для перемещения. Отлично!
Спасибо, задача решена, и я более менее разобрался в команде FOR, наконец-то понятно, для чего usebackq нужен.
Однако, так и не разобрался, хотя хотелось бы, каковы возможности работы с переменными цикла. Вообще можно ли их значения присвоить обычным переменным, затем проводить с этими обычными переменными манипуляции (обрезать, заменять и т.п.) Тогда возможно было бы выполнить эти манипуляции в рамках одного цикла? Или в CMD это невозможно, или будет еще сложнее?
Еще раз спасибо.

Iska 22-03-2017 07:51 2721950

Цитата:

Цитата londondron
и я более менее разобрался в команде FOR, наконец-то понятно, для чего usebackq нужен. »

Так для чего?

Цитата:

Цитата londondron
каковы возможности работы с переменными цикла. Вообще можно ли их значения присвоить обычным переменным, »

Можно.

Цитата:

Цитата londondron
затем проводить с этими обычными переменными манипуляции (обрезать, заменять и т.п.) »

Можно. Главное, не забывать, что раскрытие переменных окружения по %…% происходит в момент входа в операторные скобки. Потому требуется либо двойное раскрытие по call … %%SomeVar%%, либо enabledelayedexpansion и !SomeVar!.

Цитата:

Цитата londondron
Тогда возможно было бы выполнить эти манипуляции в рамках одного цикла? »

Где Вы, полагаете, лишние циклы в коде?

londondron 22-03-2017 10:48 2721989

Цитата:

Цитата Iska
Так для чего? »

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

Цитата Iska
Можно. Главное, не забывать, что раскрытие переменных окружения по %…% происходит в момент входа в операторные скобки. Потому требуется либо двойное раскрытие по call … %%SomeVar%%, либо enabledelayedexpansion и !SomeVar!. »

Это для меня немного труднее. С наскока не разберусь.
Цитата:

Цитата Iska
Где Вы, полагаете, лишние циклы в коде? »

Извиняюсь, не сразу разобрал последний FOR, поэтому не сразу понял, зачем 2-й DIR.
Получается, что в MOVE задать путь для перемещения файлов маской невозможно, для этого вызывается DIR 2-й раз.
Но... 1-й и 2-й FOR я все-таки объединил, т.к. из 1-й команды DIR сразу можно взять фамилии, стоящие до знака "_", а затем подставить их перед маской перемещаемых файлов в MOVE.
Без 2-го DIR, при том обстоятельстве, что невозможно использовать маску В ПУТИ НАЗНАЧЕНИЯ КОМАНДЫ MOVE, конечно не обойтись.
Вот мой код (здесь переменные цикла немного другие, а %BoxOut2% - заданный путь внутри папки - в вопросе я его, упрощая, не писал, т.к. хотел понять главное)
Код:

for /f "usebackq tokens=1 delims=_" %%a in (`dir "%BoxIn%\%MaskIn%" /b /a:-d`) do (
        for /f "usebackq delims=" %%b in (`dir "%BoxOut%\%MaskOut%%%a" /b /a:d`) do move "%BoxIn%\%%a%MaskIn%" "%BoxOut%\%%b\%BoxOut2%\"
        )


megaloman 22-03-2017 12:52 2722022

londondron, значения переменных цикл можно присвоить обычным переменным, затем проводить с этими обычными переменными манипуляции (обрезать, заменять и т.п.) , например
Код:

@Echo Off
cls

SetLocal EnableExtensions EnableDelayedExpansion

FOR %%d IN (01.34.6789 31.02.1812 22.03.2017) DO (
        Set "TData=%%d"
        Set "DD=!TData:~0,2!
        Set "MM=!TData:~3,2!
        Set "YYYY=!TData:~6,4!
        Echo %%d  !DD!  !MM!  !YYYY! 
)


pause


Iska 22-03-2017 14:37 2722062

Цитата:

Цитата londondron
usebackq - режим обработки кавычек. Строка, заключенная в обратные кавычки, выполняется как команда, строка, заключенная в прямые одиночные кавычки, является строкой символов, а двойные кавычки могут использоваться для задания имен файлов, содержащих пробелы. »

Правильно, Сигизмунд, это Евтушенко ;)!

megaloman, покажите ему ещё разницу при использовании % и !.

megaloman 22-03-2017 14:57 2722068

Iska, Я не берусь выступать в роли безусловного авторитета, я не волшебник, я постоянно учусь, в том числе и у Вас :) Если Вы меня натыкАете носом в неточности и ошибки, всегда воспринимаю с благодарностью
londondron, Вот еще пример
Код:

@Echo Off
cls

FOR %%d IN (01.34.6789 31.02.1812 22.03.2017) DO (
        Set "TData=%%d"
        Call Set "DD=%%TData:~0,2%%"
        Call Set "MM=%%TData:~3,2%%"
        Call Set "YYYY=%%TData:~6,4%%"
        call Echo %%d  %%DD%%  %%MM%%  %%YYYY%% 
)

pause


Iska 22-03-2017 15:22 2722077

Цитата:

Цитата megaloman
Я не берусь выступать в роли безусловного авторитета, я не волшебник, »

А придётся :).


Время: 13:50.

Время: 13:50.
© OSzone.net 2001-