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

qaaqasqad 02-03-2017 18:29 2716112

Пробел вместо нуля в разряде десятков часов
 
При добавлении текущего времени к имени файла (или папки), при создании папки с текущим временем в имени и многих других случаях, где используется %time:~0,2% , имеем пробел вместо нуля в разряде десятков часов, если часы не перевалили за 10: Err-123- 8.06.53.log и FOLDER- 8.07.49 вместо желаемых Err-123-08.06.53.log и FOLDER-08.07.49 , что неудобно (в т.ч. при сортировке по имени). Это исправимо? Знатоки! Откликнитесь!
Код:

for %%i in (Err-*.log) do ren "%%i" "%%~ni-%time:~0,2%.%time:~3,2%.%time:~6,2%%%~xi"
md "FOLDER-%time:~0,2%.%time:~3,2%.%time:~6,2%"

Подробности: ось - WinXP SP3 Pro, в реестре:
Код:

[HKEY_CURRENT_USER\Control Panel\International]
"iTLZero"="1"
"sTimeFormat"="HH:mm:ss"

Системное время во всех местах отображается подходяще - с нулем...

x0r 02-03-2017 19:15 2716124

Я себе дату беру для имени папки по другому. так удобней:
Код:

rem взять дату заменить точки на подчеркивание, развернуть сначала год_месяц_день
for /f "delims=. tokens=1,2,3" %%i  in ("%date%") do set d=%%k_%%j_%%i
rem echo %d%

подчеркивания можно заменить на '-' или др.

... тоже самое и с временем, чуть изменив:
Код:

rem взять время  заменить точки на подчеркивание.
for /f "delims=:, tokens=1,2,3" %%i  in ("%time%") do set t=%%i_%%j_%%k
echo %t%
pause


megaloman 02-03-2017 20:26 2716139

qaaqasqad, вот Ваш код без пробела
Код:

Set "time1=%time: =0%"
Set "time1=%time1:~0,2%.%time1:~3,2%.%time1:~6,2%"

for %%i in (Err-*.log) do ren "%%i" "%%~ni-%time1%%%~xi"
md "FOLDER-%time1%"


greg zakharov 02-03-2017 22:04 2716162

Код:

@echo off
  setlocal enabledelayedexpansion
    call:getsafetime "."
    echo:%time%
  endlocal
exit /b

:getsafetime
  set "time=%time:~0,-3%" % rem : отбросить миллисекунды
  set "time=%time: =%"    % rem : удалить пробелы
  if /i "%~1" neq "" (
    set "time=!time::=%~1!"
  ) else (set "time=%time::=%")
exit /b


qaaqasqad 03-03-2017 01:00 2716198

greg zakharov
Спасибо. Постараюсь осилить (см. P.S.)

x0r
Спасибо. С %date% все прошло гладко. О %time% : ну не заработал у меня этот и еще пара-тройка подобных ему сценариев, пока вручную не поставил точки в качестве разделителей компонентов системного времени (а это меня не устраивает). А когда извлеченное из системы время все же вставилось куда нужно, то при HH<10 вместо нуля в разряде десятков часов обнаружился все тот же пробел... И все равно было очень познавательно. Еще раз спасибо.

megaloman
Спасибо. Очень компактно и эффективно. Все заработало как положено, и нужные нули - в нужных местах без мороки (да Вы и сами знаете). Добавил (по аналогии) вставку даты, разумный твик реестра (чтобы без сюрпризов), подобрал компактные разделители (дело вкуса). И вот что вышло:
Код:

Reg.exe add "HKCU\Control Panel\International" /v "s1159" /t REG_SZ /d "" /f
Reg.exe add "HKCU\Control Panel\International" /v "s2359" /t REG_SZ /d "" /f
Reg.exe add "HKCU\Control Panel\International" /v "sDate" /t REG_SZ /d "." /f
Reg.exe add "HKCU\Control Panel\International" /v "sTime" /t REG_SZ /d ":" /f
Reg.exe add "HKCU\Control Panel\International" /v "sShortDate" /t REG_SZ /d "yyyy.MM.dd" /f
Reg.exe add "HKCU\Control Panel\International" /v "iTLZero" /t REG_SZ /d "1" /f
Reg.exe add "HKCU\Control Panel\International" /v "sTimeFormat" /t REG_SZ /d "HH:mm:ss" /f

Set "date1=%date: =0%"
Set "date1=%date1:~0,4%'%date1:~5,2%'%date1:~8,2%"
Set "time1=%time: =0%"
Set "time1=%time1:~0,2%'%time1:~3,2%'%time1:~6,2%"

for %%i in (Err-*.log) do ren "%%i" "%%~ni_%date1%`%time1%%%~xi"
md "FOLDER_%date1%`%time1%"

(последние две строки - как примеры использования)
А вот и желаемый продукт: Err-123_2017'03'02`06'12'19.log и FOLDER_2017'03'02`06'12'19 !
Всем большое спасибо!

P.S. До этого на тему CMD/BAT не заморачивался...

x0r 03-03-2017 16:41 2716384

Цитата:

Цитата qaaqasqad
О %time% : »

Сделай еще одну оп-цию с переменной:
Код:

rem взять время  заменить точки на подчеркивание.
for /f "delims=:, tokens=1,2,3" %%i  in ("%time%") do (set t=%%i_%%j_%%k)
set t=%t: =0%
echo %t%
pause

.. и будет тебе нуль :)

qaaqasqad 04-03-2017 00:49 2716495

x0r
Спасибо. "Обнулился" :) (в хорошем смысле). Наилучший вариант, т. к. (это я уже о %date% и о методе в целом) нормально вставляет дату при любых системных настройках ее краткого формата типа dd.MM.yyyy или d.M.yy (конечно, о сортировке по имени речь уже не будет идти, но все равно приятно). А от "зкзотических" разделителей компонентов даты и времени (моя вчерашняя загвоздка) :biggrin: спасет delims=.:,;-_`/|\ (с перебором, но на всякий случай). В итоге пришел к такому:
Код:

::Reg.exe add "HKCU\Control Panel\International" /v "sShortDate" /t REG_SZ /d "yyyy.MM.dd" /f
for /f "delims=.:,;-_`/|\ tokens=1,2,3" %%i  in ("%date%") do (set dateX=%%i'%%j'%%k)
for /f "delims=.:,;-_`/|\ tokens=1,2,3" %%i  in ("%time%") do (set timeX=%%i'%%j'%%k)
set timeX=%timeX: =0%
md "FLDR`%dateX%`%timeX%"

(При необходимости - раскомментировать первую строку; последняя строка - для примера).
На выходе (при yyyy/MM/dd в системе) получается: FLDR`2017'03'04`06'55'56 :up
Еще раз всем спасибо!

megaloman 04-03-2017 17:30 2716642

qaaqasqad, А что если так:
Код:

FOR /F "tokens=1,2,3,4,5,6 delims=.:,;-_`/|\" %%i IN ("%date%-%time: =0%") DO Set "Dtime=%%i'%%j'%%k`%%l'%%m'%%n"
Echo %Dtime%

или эдак:
Код:

FOR /F "tokens=1,2,3,4,5,6 delims=.:,;-_`/|\" %%i IN ("%date%-%time: =0%") DO md "FLDR`%%i'%%j'%%k`%%l'%%m'%%n"

x0r 04-03-2017 20:36 2716717

Цитата:

Цитата qaaqasqad
с перебором, но на всякий случай »

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

alpap 05-03-2017 00:19 2716761

по моему, так:
Код:

@echo off
set "sdate=%date:~6%'%date:~3,2%'%date:~0,2%"
set "ntime=%time:~0,8%"
set "stime=%ntime::='%"
md "FLDR`%sdate: =0%`%stime: =0%"
pause

как-то понятнее и без извращений с перебором ...

qaaqasqad 05-03-2017 13:57 2716895

alpap
Это дает результат, пригодный для сортировки по имени (типа FLDR`2017'03'04`04'06'17 ), только при системном формате даты dd.MM.yyyy . Попробуйте это же запустить при yyyy.MM.dd или при d/M/yy ...

megaloman
Ваши методы отлично копируют системные последовательности компонентов датывремени при любых разумных разделителях, однако результат типа FLDR`2017'03'04`04'06'17 получается только при yyyy/MM/dd (хоть и с любыми разделителями).

qaaqasqad (сам себе)
Или результат типа FLDR`2017'03'04`04'06'17 не гарантирован, или твик реестра "sShortDate"="yyyy.MM.dd" так и останется в системе...

А что, если так (и результат абсолютно не зависит от системного формата датывремени, и сам этот формат в итоге возвращается в систему):
Код:

reg copy "HKCU\Control Panel\International" "HKCU\0" /s /f | reg add "HKCU\Control Panel\International" /v "sShortDate" /t REG_SZ /d "yyyy.MM.dd" /f
for /f "tokens=1,2,3,4,5,6 delims=.:,;-_`/|\" %%i in ("%date%-%time: =0%") do set "datetime=%%i'%%j'%%k`%%l'%%m'%%n"
reg copy "HKCU\0" "HKCU\Control Panel\International" /s /f | reg delete "HKCU\0" /f
md "FLDR`%datetime%"

Есть идеи, как без сильного разрастания кода и без ущерба функциональности вернуть delims к неизвращенному состоянию (и есть ли в этом смысл)?

x0r 05-03-2017 14:21 2716902

Цитата:

Цитата qaaqasqad
вернуть delims к неизвращенному состоянию (и есть ли в этом смысл)? »

никакого изврата нету. этот перебор, это пол такта проца ;-) Ежлиб были в консоли регулярки, былоб \W и все. но т.к. их нету, то набор символов и это норм.

alpap 06-03-2017 02:54 2717088

Цитата:

Цитата qaaqasqad
и есть ли в этом смысл »

Цитата:

Цитата qaaqasqad
при yyyy.MM.dd или при d/M/yy ... »

если уж хотите точно быть уверены чтобы поставить в нужном порядке при любом формате и разделителе, то:
Код:

@echo off
for /f "tokens=1* delims==" %%a in ('"wmic path win32_localtime get Day,Month,Year,Hour,Minute,Second /value|find "^=""') do set "%%a=0%%b"
md "FLDR`%Year:~-5%'%Month:~-3%'%Day:~-3%`%Hour:~-3%'%Minute:~-3%'%Second:~-3%"
pause

этот же class и в PS, там еще проще и короче.

qaaqasqad 07-03-2017 14:48 2717410

alpap
Спасибо! Идеально! Не к чему придраться! Лучше и быть не может! :laiel:

dassen 14-04-2018 12:58 2808829

alpap
А можно ли подобным образом добавить к имени файла дату-время его создания (изменения), т.е., например,
file.ext -> file`1988'09'24`21'55'51.ext ?

alpap 14-04-2018 14:55 2808846

dassen,
для такого случая достаточно:
Код:

@echo off
call :# "file.txt"
pause& exit

:#
 set "mt=%~t1"
 ren "%~1" "%~n1-%mt::='%%~x1"
exit /b


megaloman 14-04-2018 16:42 2808886

Если не думать о формате даты в системе, то wmic
Код:

@Echo Off
        Call :WRen "E:\Основная папка\тра ля ля.exe"
GoTo :Eof

:WRen
SetLocal
        If Not Exist %1 Exit /B 2
        Set "Fin=%~1"
        Set "Fin=%Fin:\=\\%"
            For /f "tokens=1* delims=," %%a in ('wmic datafile where "name='%Fin%'" get 'Creation Date' /format:csv') Do (
                If /I "%%a"=="%ComputerName%" Set "Df=%%b"
        )
        Ren %1 "%~n1`%Df:~0,4%'%Df:~4,2%'%Df:~6,2%`%Df:~8,2%'%Df:~10,2%'%Df:~12,2%%~x1" ||Exit /B 1
EndLocal
Exit /B 0

Вместо Creation Date можно запросить Last Modified

DJ Mogarych 14-04-2018 18:34 2808907

Тоже столкнулся с таким поведением командной строки, когда хотел, чтобы логи robocopy назывались по датам.
В результате самым простым методом стало просто перевести всё в Powershell.
Код:

$t = get-date -UFormat "%Y-%m-%d_%H-%M-%S"
ROBOCOPY C:\temp D:\Temp /MIR /TEE /NP /LOG:log_$t.txt


dassen 26-08-2018 19:22 2828639

megaloman, спасибо.
А если нужно добавить дату-время изменения к имени файла file.ext , лежащего в одной папке с этим батником?
( Call :WRen "file.ext" не прокатывает... )

megaloman 26-08-2018 20:05 2828651

dassen,
Код:

Call :WRen "%~dp0file.ext"
Если надо не дата-время создания, а изменения, то заменить
'Creation Date' на 'Last Modified'

dassen 04-11-2022 19:25 2995621

megaloman,
а как добавить дату-время к множеству файлов (например, *.iso)? Пробовал так:
Код:

@Echo Off
for %%i in (*.iso) do (

        Call :WRen "%~dp0%%i"
GoTo :Eof

:WRen
SetLocal
        If Not Exist %1 Exit /B 2
        Set "Fin=%~1"
        Set "Fin=%Fin:\=\\%"
            For /f "tokens=1* delims=," %%a in ('wmic datafile where "name='%Fin%'" get 'Creation Date' /format:csv') Do (
                If /I "%%a"=="%ComputerName%" Set "Df=%%b"
        )
        Ren %1 "%~n1`%Df:~0,4%'%Df:~4,2%'%Df:~6,2%`%Df:~8,2%'%Df:~10,2%'%Df:~12,2%%~x1" ||Exit /B 1
EndLocal

)
Exit /B 0

, но таким способом обрабатывается только один iso-файл (первый по имени)...

DJ Mogarych 04-11-2022 21:31 2995628

Powershell:
Код:

dir C:\temp\*.iso |Rename-Item -NewName {$_.BaseName + $_.CreationTime.ToString("yyyy-MM-dd_HH-mm-ss") + $_.extension} -WhatIf
Уберите -whatif, чтобы реально переименовывало. Формат даты подправьте, если надо.

megaloman 04-11-2022 21:48 2995632

Код:

@Echo Off
        Call :WRenMask "Z:\Основная папка\*.iso"
GoTo :Eof

:WRenMask
SetLocal
        If Not Exist %1 Exit /B 2
        For %%f In (%1) Do (
                Set "Fin=%%~f"
                Call Set "Fin=%%Fin:\=\\%%"
                For /f "tokens=1* delims=," %%a in ('Call wmic datafile where "name='%%Fin%%'" get 'Creation Date' /format:csv') Do (
                        If /I "%%a"=="%ComputerName%" (
                                Set "Df=%%b"
                                Call Ren "%%~f" "%%~nf`%%Df:~0,4%%'%%Df:~4,2%%'%%Df:~6,2%%`%%Df:~8,2%%'%%Df:~10,2%%'%%Df:~12,2%%%%~xf"
                        )
                )
        )
EndLocal
Exit /B


megaloman 04-11-2022 22:11 2995637

Торможу, пока въехал в смысл кода, можно было процедуру и не менять
Код:

@Echo Off
        For %%f In ("Z:\Основная папка\*.iso") Do Call :WRen "%%~f"
GoTo :Eof

:WRen
SetLocal
        If Not Exist %1 Exit /B 2
        Set "Fin=%~1"
        Set "Fin=%Fin:\=\\%"
            For /f "tokens=1* delims=," %%a in ('wmic datafile where "name='%Fin%'" get 'Creation Date' /format:csv') Do (
                If /I "%%a"=="%ComputerName%" Set "Df=%%b"
        )
        Ren %1 "%~n1`%Df:~0,4%'%Df:~4,2%'%Df:~6,2%`%Df:~8,2%'%Df:~10,2%'%Df:~12,2%%~x1" ||Exit /B 1
EndLocal
Exit /B 0


dassen 05-11-2022 18:00 2995724

megaloman, спасибо.
1. Код2 компактнее, но... Если использовать Код2 в составе другого батника (но не в его конце!), то последняя строка Exit /B 0, естественно, недопустима. А если ее нет (а далее идут другие строки!), то обрабатывается только один iso-файл (первый по имени). При тех же условиях: Код1 обрабатывает все файлы даже без своей последней строки Exit /B .
Для иллюстрации: запустите оба Кода в их теперешнем виде, заменив только их последние строки на, например, notepad или pause.
2. Апостроф (или английская одиночная кавычка) в имени файла недопустим (т.к. уже используется в Коде), поэтому обработка файлов по второму кругу заканчивается ошибками. Учту...
3. В составе большого батника уже успешно использую Код1 в таком несколько сокращенном виде:
Код:

if exist "*.iso" (
    echo Старые *.iso : переименование и перемещение в ISO-OLD\ . . .
        call :wrenmask "%~dp0*.iso"
        :wrenmask
                for %%f in (%1) do (
                        set "Fin=%%~f"
                        call set "Fin=%%Fin:\=\\%%"
                        for /f "tokens=1* delims=," %%a in ('call wmic datafile where "name='%%Fin%%'" get 'LastModified' /format:csv') do if /i "%%a"=="%ComputerName%" (
                                set "Df=%%b"
                                if not exist "ISO-OLD" md "ISO-OLD"
                                call move "%%~f" "ISO-OLD\%%~nf--%%Df:~2,6%%-%%Df:~8,4%%%%~xf"
                        )
                )
    if exist "*.iso" (echo. && echo          Некоторые старые *.iso остались на прежнем месте - доступ?)! && echo. && pause && exit)
    echo    переименованы и перемещены
    echo.
)

Но ведь работает же! Критикуйте, если что...
4. На текущий момент главная задача Вашими усилиями уже решена, но все же:
вот бы так же применить Код2...

megaloman 05-11-2022 20:11 2995744

dassen, Не сильно понял, что Вы хотите и чем Вас мой код не устроил, то ли с процедурой :WRenMask то ли :WRen
Поговорим о структуре скрипта:
Код:

@Echo Off
        Call :WRenMask "Z:\Основная папка\*.iso"
GoTo :Eof

Код:

@Echo Off
        For %%f In ("Z:\Основная папка\*.iso") Do Call :WRen "%%~f"
GoTo :Eof

GoTo :Eof можно заменить Exit /B, но это не играет никакой роли. Главное, есть блок кода (условно назовём главный), в котором вызывается процедура. В первом случае просто Call, во втором - Call в цикле. Не надо, как Вы в начале сделали, под тело цикла помещать процедуру. Рассматривайте процедуру как отдельную программную единицу.
Если хотите что-то делать после её отработки - продолжайте развивать главный код.
Код:

@Echo Off
........Если что-то надо дописать в начале
........Если что-то надо дописать в начале
........Если что-то надо дописать в начале
        Call :WRenMask "Z:\Основная папка\*.iso"
........Если что-то надо дописать после вызова процедуры
........Если что-то надо дописать после вызова процедуры
........Если что-то надо дописать после вызова процедуры
GoTo :Eof

Код:

@Echo Off
........Если что-то надо дописать в начале
........Если что-то надо дописать в начале
........Если что-то надо дописать в начале
        For %%f In ("Z:\Основная папка\*.iso") Do Call :WRen "%%~f"
........Если что-то надо дописать после вызова процедуры
........Если что-то надо дописать после вызова процедуры
........Если что-то надо дописать после вызова процедуры
GoTo :Eof

Убедитесь сами - поставьте перед GoTo :Eof
Цитата:

Цитата dassen
например, notepad или pause. »

Если надо изваять еще процедуру(ы), то после или GoTo :Eof или Exit вставляете свой код Вашей процедуры (не внутри главной части, не внутри старой процедуры), например:
Код:

:NameMyProcedure
      ..... Ваше творчество
Exit /B

и вызывайте эту процедурищу колом в главной части.
Предыдущие процедуры, подправленные для Move
Код:

@Echo Off
cls
        Set "BoxOut=Z:\Основная папка\Moved and renamed"
        If Not Exist "%BoxOut%\" Md "%BoxOut%"
        Call :WMoveMask "Z:\Основная папка\*.iso"
Echo Ура!
Pause
Exit /B

:WMoveMask
SetLocal
        If Not Exist %1 Exit /B 2
        For %%f In (%1) Do (
                Set "Fin=%%~f"
                Call Set "Fin=%%Fin:\=\\%%"
                For /f "tokens=1* delims=," %%a in ('Call wmic datafile where "name='%%Fin%%'" get 'Creation Date' /format:csv') Do (
                        If /I "%%a"=="%ComputerName%" (
                                Set "Df=%%b"
                                >nul Call Move "%%~f" "%BoxOut%\%%~nf_%%Df:~0,4%%.%%Df:~4,2%%.%%Df:~6,2%%-%%Df:~8,2%%.%%Df:~10,2%%.%%Df:~12,2%%%%~xf"
                        )
                )
        )
EndLocal
Exit /B

Код:

@Echo Off
cls
        Set "BoxOut=Z:\Основная папка\Moved and renamed"
        If Not Exist "%BoxOut%\" Md "%BoxOut%"
        For %%f In ("Z:\Основная папка\*.iso") Do Call :WMove "%%~f"
Echo Ура!
Pause
GoTo :Eof

:WMove
SetLocal
        If Not Exist %1 Exit /B 2
        Set "Fin=%~1"
        Set "Fin=%Fin:\=\\%"
            For /f "tokens=1* delims=," %%a in ('wmic datafile where "name='%Fin%'" get 'Creation Date' /format:csv') Do (
                If /I "%%a"=="%ComputerName%" Set "Df=%%b"
        )
        >nul Move %1 "%BoxOut%\%~n1`%Df:~0,4%'%Df:~4,2%'%Df:~6,2%`%Df:~8,2%'%Df:~10,2%'%Df:~12,2%%~x1" ||Exit /B 1
EndLocal
Exit /B 0

А разделители аккуратненько поставьте свои, или уберите вообще - не смею ограничивать Вашу свободу :)

dassen 05-11-2022 21:33 2995747

megaloman, еще раз спасибо.
Цитата:

Цитата megaloman
чем Вас мой код не устроил »

На 100% устроил Код1 (тот, который с процедурой :WRenMask), он уже реально работает в составе моего батника. И это главное :good:.
В теории CMD/BAT я не силен (мягко сказано!) :lamer: , просто мне иногда бывает нужно с помощью CMD/BAT решить конкретную задачу (в простых случаях справляюсь сам).
Ваше сегодняшнее сообщение попытаюсь осилить и еще задам вопросы. :bow:

DJ Mogarych 07-11-2022 16:55 2995895

Переходите на Powershell, там меньше текста осиливать надо.


Время: 22:39.

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