2009-08-18 89 views
77

只是將一些shell腳本轉換爲批處理文件,並且有一件事我無法找到......並且這是一個簡單的命令行參數數量。批處理文件 - 命令行參數的數量

例如。如果您有:

myapp foo bar 

在殼牌:

  • $# - > 2
  • $ * - > FOO吧
  • $ 0 - > MYAPP
  • $ 1 - 「FOO
  • $ 2 - > bar

在批次

  • ?? - > 2 < ----什麼命令?!
  • %* - > FOO吧
  • %0 - > MYAPP
  • %1 - >富
  • %2 - >酒吧

所以我環顧四周,並任我在尋找錯誤的地方或我是盲目的,但我似乎無法找到一種方法來獲得通過的命令行參數的數量的計數。

是否有類似於shell的「$# 「批處理文件?

ps。我發現的最接近的是遍歷%1s並使用'shift',但在腳本後面需要引用%1,%2等,所以這沒什麼用。

+0

您的字符串是'2 MYAPP富bar'? – PsychoData 2014-02-05 00:29:39

+2

建議:不要將sh轉換爲BAT。相反,請下載cygwin並使用它。即您的sh腳本將在Windows機器上工作。你不需要翻譯每一個噓到英美菸草! – 2015-04-15 16:09:52

回答

81

谷歌上搜索了一下讓你從wikibooks以下結果:

set argC=0 
for %%x in (%*) do Set /A argC+=1 

echo %argC% 

似乎cmd.exe已經從舊的DOS天進化了一下:)

+7

請注意,這個'for'的變體只適用於看起來像文件名的參數,而不是像' - ?'這樣的選項字符串。使用引號('%for %%'in(「%*」)...')適用於像' - ?'這樣的參數,但由於嵌套引號而引用的參數失敗。唯一強大的方式似乎涉及'轉移'... – 2013-08-23 12:35:36

+1

對不起,downvoted因爲@FerdinandBeyer說 – n611x007 2013-08-23 18:50:42

33

你往往處理的參數的個數與這種邏輯:

IF "%1"=="" GOTO HAVE_0 
IF "%2"=="" GOTO HAVE_1 
IF "%3"=="" GOTO HAVE_2 

如果你有超過900名的參數,那麼你擰這種方法雖然。有各種創建計數器的黑客,你可以找到here,但要警告這些不適合膽小的人。

+3

你仍然可以使用'shift'來計算超過9 ...並且沒有10行相同的代碼。 – Joey 2009-09-30 13:13:47

18

以下功能:getargc可能是您正在尋找的。

@echo off 
setlocal enableextensions enabledelayedexpansion 
call :getargc argc %* 
echo Count is %argc% 
echo Args are %* 
endlocal 
goto :eof 

:getargc 
    set getargc_v0=%1 
    set /a "%getargc_v0% = 0" 
:getargc_l0 
    if not x%2x==xx (
     shift 
     set /a "%getargc_v0% = %getargc_v0% + 1" 
     goto :getargc_l0 
    ) 
    set getargc_v0= 
    goto :eof 

它基本上一次迭代在列表上(這是本地的功能,使該轉變將不會影響列表回到主程序),計數,直到用完。

它還使用了一個漂亮的技巧,傳遞函數設置的返回變量的名稱。

主程序只是說明了如何把它和回聲的參數之後,以確保它們是不變:

C:\Here> xx.cmd 1 2 3 4 5 
    Count is 5 
    Args are 1 2 3 4 5 
C:\Here> xx.cmd 1 2 3 4 5 6 7 8 9 10 11 
    Count is 11 
    Args are 1 2 3 4 5 6 7 8 9 10 11 
C:\Here> xx.cmd 1 
    Count is 1 
    Args are 1 
C:\Here> xx.cmd 
    Count is 0 
    Args are 
C:\Here> xx.cmd 1 2 "3 4 5" 
    Count is 3 
    Args are 1 2 "3 4 5" 
+0

你如何根據這個改變流程? (可能是一個不同的問題,但我認爲一個簡短的例子在這裏也會很方便!) – n611x007 2013-08-23 18:53:43

+0

@ n611x007其中'echo Count是%argc%'你可以插入你自己的代碼來檢查計數是否正確,然後繼續。 – kenny 2017-03-27 14:14:16

6

試試這個:

SET /A ARGS_COUNT=0  
FOR %%A in (%*) DO SET /A ARGS_COUNT+=1  
ECHO %ARGS_COUNT% 
+5

是這個答案不同於[@nimrod one](http://stackoverflow.com/a/1292094/505893) ?... – bluish 2012-05-17 13:27:48

+0

查看@FerdinandBeyer在nimrodm的評論。不會因爲你有21代表而失望8) – n611x007 2013-08-23 18:51:56

5

如果參數的數量應爲一個確切的數字(9小於或等於),那麼這是一個簡單的方法來檢查它:

if "%2" == "" goto args_count_wrong 
if "%3" == "" goto args_count_ok 

:args_count_wrong 
echo I need exactly two command line arguments 
exit /b 1 

:args_count_ok 
2

避免了使用任一shift或在for週期尺寸和可讀性的成本。

@echo off 
setlocal EnableExtensions EnableDelayedExpansion 
set /a arg_idx=1 
set "curr_arg_value=" 
:loop1 
if !arg_idx! GTR 9 goto :done 
set curr_arg_label=%%!arg_idx! 
call :get_value curr_arg_value !curr_arg_label! 
if defined curr_arg_value (
    echo/!curr_arg_label!: !curr_arg_value! 
    set /a arg_idx+=1 
    goto :loop1 
) 
:done 
set /a cnt=!arg_idx!-1 
echo/argument count: !cnt! 
endlocal 
goto :eof 

:get_value 
(
    set %1=%2 
) 

輸出:

count_cmdline_args.bat testing more_testing arg3 another_arg 

%1: testing 
%2: more_testing 
%3: arg3 
%4: another_arg 
argument count: 4 

編輯:這裏使用的 「特技」 涉及:

  1. 構建一個代表當前評估的命令行參數變量的字符串(即,「% 1" ,‘使用含有百分號(%%)和每次循環迭代計數器變量arg_idx字符串%2’等)。

  2. 存儲該字符串轉換成可變curr_arg_label

  3. 將該字符串(!curr_arg_label!)和返回變量的名稱(curr_arg_value)傳遞給原始子程序get_value

  4. 在子程序的第一個參數的(%1)值被用在分配(set)和在右側的第二參數的(%2)值的左側。但是,當第二個子程序的參數被傳遞時,它將被命令解釋器解析爲主程序的命令行參數的值。也就是說,傳遞的內容不是,例如「%4」,但是第四個命令行參數變量保存的值(示例用法中的「another_arg」)。

  5. 然後,將給予子程序的變量作爲返回變量(curr_arg_value)進行測試,以確定是否未定義,如果當前評估的命令行參數不存在,則會發生這種情況。最初,這是將方括號中包含的返回變量的值與空方括號(這是我知道測試程序或子程序參數可能包含引號的唯一方式,並且是從試錯階段遺漏的剩餘部分)的比較,但是自從現在被固定到現在。

+1

雖然這段代碼可能回答這個問題,但提供關於如何和/或爲何解決問題的附加背景將會提高答案的長期價值。 – thewaywewere 2017-06-09 02:35:11

+0

@thewaywewere謝謝,我一直忘記,對於很多人(可能是大多數人),最好是有一個文字說明,而不是「不言自明」的代碼。 – 2017-07-16 11:27:21

相關問題