Компьютерный форум 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=348721)

epoddubniy 11-05-2021 14:38 2957534

Копирование из каталога в каталог по условию
 
Здравствуйте. Помогите пожалуйста.

chcp 65001

rem объявляю переменные

set DirNaznachenie="Z:\kuda_kopiruestya"
set DirNaznachenieFile="Z:\kuda_kopiruestya\DirNaznachenieFile.txt"
set FindstrResultatFile="Z:\kuda_kopiruestya\FindstrResultatFile.txt"
set DirNaznachenieMmYyyy="Z:\kuda_kopiruestya\%mmyy%"
set mm=%date:~3,2%
set yy=%date:~8,2%
set yyyy=%date:~6,4%
set mmyy=%mm%.%yy%
set mmPlus="%mm%*"
set TekGod="Z:\otkuda_kopiruestya\%yyyy%"
set TekGodMesyac="Z:\otkuda_kopiruestya\%yyyy%\%mm%"
set TekGodMesyacPlus="Z:\otkuda_kopiruestya\%yyyy%\%mmPlus%"

rem проверка существования директории-источника, то есть создал ли пользователь дирекорию, которая будет наполняться целевыми файлами

if exist %TekGodMesyacPlus% goto :ProverkaDirNaznach
if not exist %TekGodMesyacPlus% goto :end

:ProverkaDirNaznach

rem получаем список имен каталогов в директории назначения и сохраняем в файл, чтобы проверить, не создан ли уже каталог с наименовнаием %mmyy%

dir /b /d %DirNaznachenie% > %DirNaznachenieFile%

rem проверяем есть ли в директории каталог, в имени которого текущий месяц и год (по условию), то есть, например каталог с наименованием 05.21

findstr /c:%mmyy% %DirNaznachenieFile% > %FindstrResultatFile%

rem если, ниже, в команде for не будет usebackq и выражение будет в '' кавычках, то вывод будет Z:\PTO, а не ожидаемый, поэтому кавычки убираем, usebackq добавляем
rem если есть, то выход и удаление текстовых файлов, копирование файлов в созданный каталог, если нет, то создается директория (а потом - также, копируются файлы *.xls, удаляются созданные *.txt

FOR /F "usebackq tokens=1 delims= " %i in (%FindstrResultatFile%) do if %i equ "" goto :procedura else goto :end

:procedura
mkdir %DirNaznachenieMmYyyy%
del %DirNaznachenieFile%, %FindstrResultatFile%
goto :kopirovanie
exit

:kopirovanie
xcopy /d %TekGodMesyacPlus%\408*.xls %DirNaznachenieMmYyyy%
exit

:end


Застопорился тут:

FOR /F "usebackq tokens=1 delims= " %i in (%FindstrResultatFile%) do if %i equ "" goto :procedura else goto :end

По какой-то не понятной мне причине не переходит к :procedura

В данном случае в файле FindstrResultatFile.txt - ничего нет, он пустой. Сравниваю тоже с пустым значением, но почему-то не переходит дальше.

Пробовал
FOR /F "usebackq tokens=* delims= "
FOR /F "usebackq tokens=*"
FOR /F "usebackq"

Все равно не переходит...

Помогите пожалуйста разобраться и сделать, чтобы был переход к процедуре

alpap 11-05-2021 15:01 2957539

epoddubniy,
просто опишите задачу что требуется и как хочется, а мы поможем.

Elven 12-05-2021 11:17 2957610

1. используйте тег code
2. не используйте goto там где это ненужно (в приведенном коде - нигде не нужно)
3. выдергивать куски даты из переменной %date% - не самый надежный вариант (при запуске на компьютерах с другими региональными настрйками они могут как минимум поменяться местами), можно дергать через wmic или запрашивать из pwsh
где-то на предыдущем пункте я понял почему alpap сразу затребовал условие, вместо ковырятельства в листинге
4. кстати за pwsh: почему не PowerShell?
5. Зачем собирать данные по наличию каталогов по маске и складывать их в файл, чтобы потом из этого файла проводить аналогичную проверку?
6. "usebackq tokens=1 delims= "
6.1. вижу пробел после delims=, если он там действительно есть, то for пытается разделить значения в файле через пробел, а раз файл пустой, то разделять нечего, разумеется цикл не проходит.
6.2. если пробел таки опечатка (что логично предположить) и выдергиваться должна строка (что тоже логично, туда ведь имена папок складываются, вроде бы), то зачем здесь tokens=1?

El Sanchez 12-05-2021 14:06 2957621

Цитата:

Цитата epoddubniy
Застопорился тут:
FOR /F "usebackq tokens=1 delims= " %i in (%FindstrResultatFile%) do if %i equ "" goto :procedura else goto :end »

epoddubniy, в пакетных файлах %переменная в for должна быть вида %%переменная и вы в теле пустую переменную сравниваете с парой кавычек, поэтому на метку :procedura и не переходит, нужно так - if "%%i" equ "" и т.д.
Код:

@echo off
setlocal
set mm=%date:~3,2%
set yy=%date:~8,2%
set yyyy=%date:~6,4%
set src=Z:\otkuda_kopiruestya\%yyyy%\%mm%
set dst=Z:\kuda_kopiruestya\%mm%.%yy%
xcopy "%src%\408*.xls" "%dst%" /dcfyzi


alpap 12-05-2021 15:39 2957627

если уж на то пошло там и for -то не нужен
вот логика с минимальной проверкой на живом примере:
Код:

@echo on
set DirNaznachenieFile="C:\file.txt"
set FindstrResultatFile="C:\out.txt"

echo 05.21 > %DirNaznachenieFile%
findstr /c:05.21 %DirNaznachenieFile% > %FindstrResultatFile%
<%FindstrResultatFile% set /p z=
if defined z (echo %z%) else (echo Пусто)
pause


epoddubniy 13-05-2021 19:18 2957784

Цитата:

Цитата alpap
просто опишите задачу что требуется и как хочется, а мы поможем. »

Есть каталог-источник.
В каталоге источнике каждый год пользователем А создаются папки с намиенованием года (2019, 2020, 2021...)
Также в каждом из этих каталогов, после перехода на новый месяц, создаются подкаталоги такого формата: 01 январь, 02 февраль, 03 март и т.д.
В каждый из этих каталогов ежедневно с понедельника по пятницу сохраняются файлы расширения .xls в наименовании которых есть последовательность симоволов "408*_21"
Есть каталог-назначение, в котором в зависимости от месяца и года создаются каждый месяц подкаталоги такого формата: 01.21, 02.21, 03.
Цитата:

Цитата epoddubniy
FOR /F "usebackq tokens=1 delims= " %i in (%FindstrResultatFile%) do if %i equ "" »

21 и т.д.
Каждый месяц пользователь Б копирует в соответствующую папку (например, текущий месяц май, следовательно будут копироваться файлы из директории "05 май" в "05.2021")
а также переименовывает эти файлы, то есть "408*_21" становится "408*_2021".
Оба каталога находятся на сетевой шаре.

Цитата:

Цитата Elven
1. используйте тег code
2. не используйте goto там где это ненужно (в приведенном коде - нигде не нужно) »

не могу понять, объясните пожалуйста, в чем отличие? Если есть возможность, пожалуйста, на каком-нибудь примере. Спасибо!
Цитата:

Цитата El Sanchez
epoddubniy, в пакетных файлах %переменная в for должна быть вида %%переменная и вы в теле пустую переменную сравниваете с парой кавычек, поэтому на метку :procedura и не переходит, нужно так - if "%%i" equ "" и т.д. »

пакетный файл пока еще не пробовал запускать, делал пошагово в окне интерпетатора и завис на выполнении этой команды (вместо :goto прописал echo Ne suschestvuet, но при нажатии enter, не смотря на то, что в файл действительно пустой, то есть директории такой в каталоге-источнике нет, сообщения Ne suschestvuet я не получил, вместо этого просто - приглашение командной строки)
Цитата:

Цитата epoddubniy
FOR /F "usebackq tokens=1 delims= " %i in (%FindstrResultatFile%) do if %i equ "" »


megaloman 13-05-2021 22:54 2957812

Код:

@Echo Off
cls
        Set "BoxIn=\\192.168.100.23\Test1"
        Set "BoxOut=\\192.168.100.23\Test2"

        FOR /F "tokens=2 delims==." %%d in ('WMIC OS GET LOCALDATETIME /VALUE') DO Set "Now=%%d"
        Set "YYYY=%Now:~0,4%"
        Set "YY=%Now:~2,2%"
        Set "MM=%Now:~4,2%"

        Set "Mask=408*_%YY%.xls"
       
        If Not Exist "%BoxOut%\%MM%.%YYYY%" Md "%BoxOut%\%MM%.%YYYY%"

        For /f "usebackq delims=" %%d In (`2^>nul Dir /B /A:D "%BoxIn%\%YYYY%\%MM%*"`) Do (
                For /f "usebackq delims=" %%f In (`2^>nul Dir /B /A:-D "%BoxIn%\%YYYY%\%%d\%Mask%"`) Do (
                        Call :MyCopy "%BoxIn%\%YYYY%\%%d\%%f" "%BoxOut%\%MM%.%YYYY%"
                )
        )
pause
Exit /B

:MyCopy
        Set "Name=%~nx1"
        Call Set "NameNew=%%Name:_%YY%%~x1=_%YYYY%%~x1%%"
        If Not Exist "%~2\%NameNew%" (
                >nul Copy %1 "%~2\%NameNew%"
        ) Else (
                >nul Xcopy /D /Y %1 "%~2\%NameNew%"
        )
Exit /B


alpap 13-05-2021 23:24 2957813

epoddubniy, я просил описать задачу. а не то как происходит или вы не имеете права все взять в свои руки? Тогда поясните почему:
- первое
Цитата:

Цитата epoddubniy
создаются каждый месяц подкаталоги такого формата: 01.21, 02.21, 03.21 »

а не 01.2021, 02.2021, 03.2021, как требуется потом
Цитата:

Цитата epoddubniy
будут копироваться файлы из директории "05 май" в "05.2021" »

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

Цитата epoddubniy
ежедневно с понедельника по пятницу сохраняются файлы »

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

alpap 14-05-2021 03:46 2957827

PowerShell
Код:

$sSrc = 'C:\каталог источник'
$sDst = 'C:\каталог назначение'
$prf  = 408
$ext  = 'xls'
$sY  = '{0:yyyy}'          -f (Get-Date)
$sM  = '{0:MM} {0:MMMM}'  -f (Get-Date)
$sM1  = '{0:MM} {0:MMMM}'  -f (Get-Date).AddMonths(1) # Создаем заранее каталог наполнения на следующий месяц
$sMY  = '{0:MM}.{0:yyyy}'  -f (Get-Date)
$sFl  = "$prf*_{0:yy}.$ext" -f (Get-Date)

if (!(Test-Path "$sSrc\$sY\$sM1")) {ni "$sSrc\$sY\$sM1" -i Dir|Out-Null}
if (!(Test-Path "$sDst\$sMY"))    {ni "$sDst\$sMY"    -i Dir|Out-Null}
$afSrc = gci $sSrc\$sY\$sM $sFl -r -af
foreach ($i in $afSrc) {cpi $i $sDst\$sMY\$($i.Name -Replace '_\d{2}', {'_{0:yyyy}' -f (Get-Date)})}


Elven 14-05-2021 09:50 2957843

Цитата:

Цитата epoddubniy
объясните пожалуйста, в чем отличие »

Читать такое
FOR /F "usebackq tokens=1 delims= " %i in (%FindstrResultatFile%) do if %i equ "" goto :procedura else goto :end
гораздо менее удобно чем такое
Код:

FOR /F "usebackq tokens=1 delims= " %i in (%FindstrResultatFile%) do if %i equ "" goto :procedura else goto :end
ну и на всякий случай отличие от goto

Код:

FOR /F "usebackq tokens=1 delims= " %i in (%FindstrResultatFile%) do if %i equ "" (
echo вот здесь goto :procedura заменяется блоком команд
) else (
echo как и здесь goto :end
echo ну или выходом с определенным кодом, если так больше нравится
echo и голова не болит, от подозрений о где-то незакрытом goto который может выполниться не тогда когда нужно, а, например, при каждом запуске bat'ника
)


megaloman 14-05-2021 11:29 2957880

Цитата:

Цитата Elven
FOR /F "usebackq tokens=1 delims= " %%i in (%FindstrResultatFile%) do if %i equ "" ( »

Чтобы это сработало, надо, чтобы в файле первой строкой была строка "" (именно с кавычками), иначе, ИМХО, такой If под For не сработает никогда, ИМХО, For просто пропустит пустую строку. Хотелось бы посмотреть пример реального файла (epoddubniy, предоставьте пожалуйста) и придумать для него работающее решение.
epoddubniy, Вообще-то, если хотите (ИМХО, похвально!), организовывать код в виде выделенных процедур, то GoTo не годится, надо использовать Call.
У Вас, например, есть процедура:
Код:

:procedura
....
Exit /B

Если делаете GoTo :procedura - выполнение командного файла завершится. В отличии от
Call :procedura
После этого выполнение командного файла продолжится дальше

Elven 14-05-2021 12:59 2957911

Цитата:

Цитата megaloman
Чтобы это сработало »

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

alpap 14-05-2021 15:14 2957924

что вы спорите, если условие задачи вообще никуда:
копировать по условию, а условие - есть папка или нет (та, куда копируем) и если нет создаем. Я понимаю, если папки сами создаются, я и задавал выше ТС подобные вопросы поэтому. В данном случае условие это: или появление нового(ых) файла(ов) или момент запуска кода, последнее я и брал за условие в моем коде на PS.


Время: 22:30.

Время: 22:30.
© OSzone.net 2001-