簡體   English   中英

如何在批處理文件中的同一行上設置多個因變量?

[英]How can multiple dependent variables be set on the same line in a batch file?

這是受到另一篇關於Arqade的帖子的啟發 ,關於如何使用批處理腳本備份一些文件。

以下塊使用當前日期/時間字符串創建變量:

REM -- Get the current date/time stamp
set DS=%date%
set TS=%time: =0%
set mm=%DS:~4,2%
set dd=%DS:~7,2%
set yyyy=%DS:~10,4%
set hh=%TS:~0,2%
set min=%TS:~3,2%
set ss=%TS:~6,2%
set ms=%TS:~9,2%
set DT_STAMP=%yyyy%-%mm%-%dd%_%hh%.%min%.%ss%

作為腳本編寫者,將這些內容合並為一行通常很方便。 然而,在這種情況下,如果不是不可能的話,將其冷凝成單線是非常困難的。

似乎沒有辦法將多個set命令放在一行上。 使用&&&分隔命令工作正常,但右側的命令不能依賴於先前在同一行上設置的變量。

另外,還要注意該怎么time變量必須spaces用零代替0 似乎沒有辦法同時執行字符串替換在同一行上獲取子字符串。

有沒有辦法把它降到一條線? 我能得到的最接近的是兩條線:

set DS=%date% && set TS=%time: =0%
set DT_STAMP=%DS:~10,4%-%DS:~4,2%-%DS:~7,2%_%TS:~0,2%.%TS:~3,2%.%TS:~6,2%

更新

這已經收集了一些好的答案; 請允許我澄清接受的答案必須具備的內容:

  • 一個丑陋但可重復使用的單線解決方案是可以的 (上面已經提供了漂亮的版本)
  • 僅標准shell命令 (必須避免使用PowerShell和類似 命令 ;如果我想要那些,我只需要在PowerShell中執行所有操作)
  • 能夠以任何邏輯格式格式化日期(應該能夠執行以上漂亮版本可以執行的任何操作,而不僅僅是使用簡寫符號支持ISO格式的日期)
  • 可以忽略本地化設置(實際上,這只是一次!)
  • 必須在一條線上! (例如, 延遲擴展很方便,但可能有令人討厭的副作用,不能在每種情況下重復使用,通常需要多行)

這是一個微不足道的FOR / F聲明,但正如npocmaka已經說過,它取決於本地化。

我假設你的日期/時間是這樣的

Fri 09/14/2018
 8:15:46.12

然后這個工作

for /F "tokens=1-7 delims=/:,. " %%1 in ("%date% %time: =0%") do set DT_STAMP=%%4-%%2-%%3_%%5.%%6.%%7

但是對於您需要的德國本地化

for /F "tokens=1-7 delims=/:,. " %%1 in ("%date% %time: =0%") do set DT_STAMP=%%3-%%2-%%1_%%4h%%5m%%6s

使用批處理宏的解決方案

你可以構建一個批處理宏,宏的使用更具可讀性,但宏本身有點復雜

使用宏,它將當前時間戳分配給變量myDT1:

%@AssignTimeStamp% myDT1
echo %myDT1%

宏的定義(在定義宏時必須禁用延遲擴展):

REM *** Macro definition, be sure that there aren't any trailing whitespaces
set ^"LF=^
%= This creates a variable containing a single linefeed (0x0A) character =%
^"
:: Define %\M% to effectively issue a newline with line continuation
set ^"\M=^^^%LF%%LF%^%LF%%LF%^^"

set @AssignTimeStamp=for %%. in (1 2) do if %%.==2 (%\M%
    %= The next line builds the timestamp =%%\M%
    for /F "tokens=1-7 delims=/:,. " %%1 in ("%date% %time: =0%") do set timestamp=%%4-%%2-%%3_%%5h%%6m%%7s%\M%
    %= When a variable name was give then store the timestamp there, else output the timestamp =%%\M%
    for /F "tokens=1,2 delims=, " %%1 in ("#,!argv!") do ( %\M%
        for %%V in (!timestamp!) do endlocal^&if "%%~2" neq "" (set "%%2=%%V") else echo ##%%V%\M%
    )%\M%
) else setlocal enableDelayedExpansion^&set argv=,

是的,你可以 - 延遲擴展

setlocal enableDelayedExpansion&set "DS=%date%"&& set "TS=%time: =0%"&set "DT_STAMP=!DS:~10,4!-!DS:~4,2!-!DS:~7,2!_!TS:~0,2!.!TS:~3,2!.!TS:~6,2!"

但這是格式化日期時間的一種糟糕方式,因為它取決於本地化設置。為什么要在一行上執行此操作? 對於獨立設置方法,請檢查此項

您似乎想要一個類似ISO-8601的格式化日期。 無論系統的區域/文化設置如何,這都將生成格式正確的日期。 如果在.bat腳本文件中使用它,請將d變量的%字符加倍。

FOR /F %d IN ('powershell -NoLogo -NoProfile -Command Get-Date -UFormat %Y-%m-%d_%H.%M.%S') DO (SET "DT_STAMP=%d")

或者,直接在PowerShell中:

$DT_STAMP = Get-Date -UFormat %Y-%m-%d_%H.%M.%S

這可以使用動態環境變量DATETIME按要求完成,日期和時間取決於區域/國家/地區,使用命令行:

@set "DT_STAMP=%DATE:~10,4%-%DATE:~4,2%-%DATE:~7,2%_%TIME:~0,2%.%TIME:~3,2%.%TIME:~6,2%" & call set "DT_STAMP=%%DT_STAMP: =0%%"

這個命令行期望DATE有一個日期字符串,如Sat 09/15/2018TIME有一個時間字符串,如4:18:23,56並且是24小時格式。

對於給定的示例日期和時間字符串,環境變量DT_STAMP值為2018-09-15_04.18.23

更好的是使用命令行:

@set "DT_STAMP=%DATE:~-4%-%DATE:~-10,2%-%DATE:~-7,2%_%TIME:~0,2%.%TIME:~3,2%.%TIME:~6,2%" & call set "DT_STAMP=%%DT_STAMP: =0%%"

第二個版本的優點是日期字符串是否以工作日開始並不重要。 但是日期字符串必須具有格式MM/DD/YYYY (MDY)以及任何類型的分隔符,例如/. -

但大多數國家/地區使用DD.MM.YYY (DMY)(使用不同的分隔符),這需要進行少量修改:

@set "DT_STAMP=%DATE:~-4%-%DATE:~-7,2%-%DATE:~-10,2%_%TIME:~0,2%.%TIME:~3,2%.%TIME:~6,2%" & call set "DT_STAMP=%%DT_STAMP: =0%%"

另見%date:〜-4,4 %% date:〜-10,2 %% date:〜-7,2%_%time:~0,2 %% time:~3,2%是什么意思?

將所有空格替換為0是在同一命令行上通過使用第二個SET命令完成的,該命令在兩側引用環境變量DT_STAMP%%而不是%

在執行第一個SET命令之前,在將命令行解析為%期間,兩個%%cmd.exe替換。 所以最終執行的命令行是例如:

@set "DT_STAMP=2018-09-15_ 4.18.23" & call set "DT_STAMP=%DT_STAMP: =0%"

CALL的使用導致在運算符& cmd.exe之后對命令行部分進行第二次解析。 因此,第二個SET具有參數"DT_STAMP=2018-09-15_04.18.23"並且最終為環境變量DT_STAMP分配所需的日期/時間字符串。

但更好的方法是將當前的本地日期/時間字符串以所需格式獨立於區域/國家/地區設置,這也可以使用單個命令行:

@for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do @set "DT_STAMP=%%I" & call set "DT_STAMP=%%DT_STAMP:~0,4%%-%%DT_STAMP:~4,2%%-%%DT_STAMP:~6,2%%_%%DT_STAMP:~8,2%%.%%DT_STAMP:~10,2%%.%%DT_STAMP:~12,2%%"

它使用WMIC來獲取當前的本地日期/時間區域,並再次使用CALLSET重新格式化日期/時間字符串,從而不包含所需格式的空格。

請參閱我在%date上的答案%從%2016中的計划任務運行時,在批處理文件中生成不同的結果,以獲取有關此命令行如何處理WMIC輸出的說明。

順便說一下: . 通常用作文件名和文件擴展名之間的分隔符。 因此,最好也使用-而不是. 小時和分鍾之間以及分鍾和秒之間。

還有一點需要注意: call后的命令也可以是任何其他直接使用日期/時間字符串的命令,例如在文件/文件夾名稱/路徑中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM