Windows批處理文件中等效於NEQ,LSS,GTR等的符號




batch-file if-statement (2)

在批處理中,我總是在使用 if 命令時使用 == 。 (例如: if "19"=="3" echo My computer doesnt know maths

對所有其他人( LSSLEQNEQ 等)怎麼樣? 是不是有類似的東西 != 對於 NEQ ,還是我在想Unix?

我想使用符號的原因是因為我認為有人說文字或數字符號比使用文本變體更有效。

無論哪種方式,我還是想知道。 謝謝。


Windows內部命令 IF 默認只有兩個運算符:

  1. == 運行兩個參數相等的 字符串 比較,即在 strcmp 返回0時使用條件為 true strcmp
  2. not== 組合以反轉相等的字符串比較結果,即如果兩個比較的字符串 相等則條件為

所以命令行:

if "19"=="3" echo My computer doesn't know maths

使用字符串 "19""3" 運行 strcmp ,這意味著比較的字節流是十六進制的 22 31 39 22 0022 33 22 00 。 在運行字符串比較之前,不會刪除雙引號。 它們包含在字符串比較中。

在命令提示符窗口中運行命令 IF 的幫助輸出命令 if /? 。 此幫助解釋了默認情況下可用於啟用命令擴展的所有選項和其他運算符。

有一個選項 /I 可以使用 stricmp 而不是 strcmp 比較兩個不區分大小寫的參數。

例:

if /I not "%~1" == "/I" echo First argument is neither /i nor /I.

並且通過啟用的命令擴展,還有其他比較運算符: EQUNEQLSSLEQGTRGEQ

尖括號 <> 在Windows命令行上用作 重定向運算符 。 因此它們不能在 IF 條件下用作比較運算符。 還有感嘆號 ! 不可用作運算符,因為它表示啟用了延遲環境變量擴展的環境變量引用的開始/結束。 運行 set /?setlocal /?endlocal /? 有關延遲環境變量擴展的詳細信息。

Windows命令解釋器嘗試使用 strtol 將兩個參數字符串轉換為帶符號的32位整數,並使用 EQUNEQLSSLEQGTRGEQ base 0(自動檢測基數)。 如果兩個參數字符串成功,則進行整數比較,因為兩個比較的字符串是十進制數,或以 0x 十六進制數或以 0 0x 八進制數。 否則,將兩個參數字符串再次與 strcmp 進行比較,並將比較運算符應用於此函數的整數結果。

將兩個字符串參數轉換為帶符號的32位整數需要一些額外的處理器指令(一些納秒或微秒,具體取決於CPU性能)。 因此,整數比較有點慢,但不是很明顯。

例子:

if 014 EQU 12 echo Octal number 014 is equal decimal number 12.
if 0x0C EQU 12 echo Hexadecimal number 0C is equal decimal number 12.
if /I 0X0C EQU 014 Hexadecimal number 0C is equal octal number 014.

使用除 == 之外的比較運算符時忽略選項 /I 並且兩個字符串僅由數字組成,其中第一個字符也可以是解釋為減號的連字符。 這可以通過上面的第三行證明。

如果兩個參數中的一個用雙引號括起來使用 EQUNEQLSSLEQGTRGEQ 或兩個字符串中的一個不是表示整數的字符串,則總是使用 strcmpstricmp 取決於 /I 用法。 strcmpstricmp 返回一個整數作為結果,可以是負數,零或正數。 根據使用的運算符將該整數結果與整數值 0 進行比較。

例子:

if 010 NEQ "10" echo String 010 is not equal string "10".
if "100" LSS "20" echo String "100" is less than string "20".

左側的第二個字符 1 具有較低的代碼值(49 = 0x31)作為右側的第二個字符 2 (50 = 0x32),這導致 strcmp 返回負值,導致 function result LSS 0 為真。

請注意,Windows環境變量始終是字符串類型,需要使用整數比較或整數運算將其始終從字符串轉換為整數。

在大多數情況下,建議使用 string1 == string2not string1 == string2 而不是 string1 EQU string2string1 NEQ string2 來比較兩個不表示整數值的字符串,以便直接使用 strcmpstricmp 。 否則,在將字符串與 EQUNEQ 進行比較時,通過讓Windows命令處理器首次使用 strtol 無法將兩個字符串中的一個轉換為比較而浪費了一些納秒或微秒,因此 cmd.exe 運行下一個 strcmpstricmp 因為它會立即執行關於operator ==

一個更重要的事實:

只有在兩個參數中的一個包含無效字符的情況下,執行 IF 條件時, cmd.exe 才會處理字符串而不是比較器 EQUNEQLSSLEQGTRGEQ 的整數比較。 然而,在超出範圍的條件下進行整數比較,例如一個參數低於 -2147483648 或大於 2147483647 如在 IF的奇怪結果中 所討論的。

通過將兩個值比較為兩個值字符串具有相同位數的字符串,可以解決值範圍限制。 下面是一個示例,以確定文件是否具有兩個或更多 GiB ,即文件大小是 2147483648 或更多字節。

@echo off
setlocal EnableExtensions DisableDelayedExpansion
if "%~1" == "" ( set "FileName=%~f0" ) else set "FileName=%~1"
for %%I in ("%FileName%") do set "FileSize=000000000000000%%~zI"
if "%FileSize:~-16%" GEQ "0000002147483648" (
    echo "%FileName%" is greater or equal 2 GiB.
) else echo "%FileName%" is less than 2 GiB.
endlocal
pause

傳遞給批處理文件的文件的文件 FileSize 作為字符串分配給環境變量 FileSize ,並且在開頭時始終至少有15個額外的零位數。

然後將 FileSize 字符串與最後16位數字進行比較,字符串 0000002147483648 表示2 GiB(以字節為單位)。 strcmp 逐字節比較兩個相等長度的字符串,因此兩個比較字符串的每個字節只能有十六進制值0x30到0x39。 如果左字符串中的當前字節低於右字符串中的當前字節,則 strcmp 立即返回負值,這意味著文件大小小於2 GiB。 如果左字符串中的當前字節大於右字符串中的當前字節,則 strcmp 立即返回正值,這意味著文件大小大於2 GiB。 strcmp 返回0,兩個字符串是100%相同,這意味著文件大小正好是2 GiB。

請注意,使用字符串比較比較值要求兩個值具有相同的位數以獲得準確的結果。 具有較少位數的值字符串必須以正確的數量 0 前置。


不使用運算符的原因是因為它們在shell腳本中具有特殊含義。 > 用於重定向輸出; < 用於重定向輸入等

Microsoft 文檔 列出了以下運算符:

Operator | Description
EQU      | equal to
NEQ      | not equal to
LSS      | less than
LEQ      | less than or equal to
GTR      | greater than
GEQ      | greater than or equal to

此外,單詞 not 用於否定條件。

我想使用符號的原因是因為我認為有人說過文本或數字符號比使用文本變體更有效。

他們可能指的是bash及其 龐大 的運營商 目錄 。 它為整數和字符串操作數提供不同的運算符。







cmd