2009-04-17 31 views
34

在以下示例中,我想從父批處理文件中調用一個子批處理文件,並將所有其餘參數傳遞給子處理。有沒有辦法指出批處理文件中的最後n個參數?

C:\> parent.cmd child1 foo bar 
C:\> parent.cmd child2 baz zoop 
C:\> parent.cmd child3 a b c d e f g h i j k l m n o p q r s t u v w x y z 

在parent.cmd中,我需要從參數列表中去除%1,並且只將其餘參數傳遞給子腳本。

set CMD=%1 
%CMD% <WHAT DO I PUT HERE> 

我調查了使用SHIFT與%*,但這並不起作用。雖然SHIFT會將位置參數向下移動1,但%*仍然是指原始參數。

任何人有任何想法?我應該放棄並安裝Linux嗎?可悲的是,

+0

重複? http://stackoverflow.com/questions/382587/how-to-get-batch-file-parameters-from-nth-position-on – 2009-04-17 18:54:54

+0

這個問題回答了代碼,沒有工作。我在我的問題中加入了一些陳述來幫助澄清,而且看起來我從Johannes得到了一個確鑿的答案。 – Dave 2009-04-17 23:29:09

+0

哦,順便說一句,當所有的男士從其他批次調用批次時都使用call。否則調用批處理文件將不會在被調用批處理退出後繼續運行。 (可能在這裏可能沒有關係,只是一些最佳實踐:-)) – Joey 2009-04-18 06:44:49

回答

62

%*將始終擴展到所有原始參數。但是你可以使用下面的代碼片段建立包含所有變量,但第一個參數:

rem throw the first parameter away 
shift 
set params=%1 
:loop 
shift 
if [%1]==[] goto afterloop 
set params=%params% %1 
goto loop 
:afterloop 

,我認爲這是可以做到更短,不過......我不經常寫這些樣的東西:)

應該工作,雖然。

+0

正如Tbee所說,如果你在剩下的參數中有'=',這是行不通的。似乎解決這個問題的唯一真正方法是編寫一個程序來正確地提取您的參數 - cmd shell太簡陋了。 – 2011-08-20 00:08:42

+3

如果您在參數中進行了分配,則此方法失敗,例如「A = B」。然後你會得到兩個單獨的參數「a」和「b」,失去了=。 – Tbee 2010-09-03 09:22:07

+2

在這種情況下,引用該論點。 'cmd'認爲還有幾個字符也是參數分隔符,比如';'或','。 – Joey 2011-08-20 12:11:20

14

下面是使用的「for」命令

for /f "usebackq tokens=1*" %%i in (`echo %*`) DO @ set params=%%j 

該命令給第一參數「i」和其餘被分配給(由「*」表示)的一行的方法「 j「,然後用它來設置」params「變量。

+0

當第一個參數包含一個空格(引用)時,例如''「第一個參數」第二個第三'將參數設置爲'參數「第二個三分之一' – EM0 2016-04-13 09:12:54

5

可以真正做到這一點:

%* 

如果是這樣就行了嘛,那麼擴展到具有第一個參數執行的命令,以傳遞給它的所有其他參數。 :)

1

的另一種方式,而不在子shell執行ECHO(幾乎一樣Alxander鳥):

FOR /F "usebackq tokens=1*" %%I IN ('%*') DO SET params=%%J 

因此,線

%CMD% <WHAT DO I PUT HERE> 

看起來像:

FOR /F "usebackq tokens=1*" %%I IN ('%*') DO %CMD% %%J 

問題是,如果參數包含內部帶空格的帶引號的響應,cmd.exe將分析它們以適合使用(%1),但FOR將忽略引號。這個特殊情況下,如果第一個參數包含一個空格或更多空間,這很可能會損害%CMD%,例如「C:\ Program Files \ Internet Explorer \ iexplore.exe」。

所以,這裏會有另一個答案。

7

%CMD% <WHAT DO I PUT HERE> 

應改爲:

(
SETLOCAL ENABLEDELAYEDEXPANSION 
SET Skip=1 

FOR %%I IN (%*) DO IF !Skip! LEQ 0 ( 
     SET params=!params! %%I 
    ) ELSE SET /A Skip-=1 
) 
(
ENDLOCAL 
SET params=%params% 
) 
%CMD% %params% 
當然

,可以設定跳轉到任意數量的參數。

0

儘管真正的「對」的解決方案是在很多情況下卓越,簡單的東西,我會經常只保存和轉移等參數了,然後用%*像往常一樣(實際上是相同的策略,往往適用於$*[email protected]{,ba,da,k,*}sh):

例如:

:: run_and_time_me.cmd - run a command with the arguments passed, while also piping 
::      the output through a second passed-in executable 

@echo off 

set run_me=%1 
set pipe_to_me=%2 
shift 
shift 

:: or 
:: set run_me=%1 
:: shift 
:: set pipe_to_me=%1 
:: shift 

%run_me% %* | %pipe_to_me% 

無論如何,我看到了問題是長回答,但想我會博士因爲這是我沒看見的東西,因爲這是我幾年前終於碰到它時所需要的答案......然後「去......哦」。 :)

+1

移位不會影響% *因此,這將所有*原始參數傳遞給%run_me%,包括%1和%2。正如接受的答案所述,「%*將始終擴展到所有原始參數,令人傷心。 – Naaff 2016-01-12 18:23:54

0

我遇到了這個問題,雖然我面臨類似的問題,但我解決了它使用不同的方法。 我只是從輸入字符串中刪除第一個參數,而不是使用循環重新創建輸入行(如在@Joey的答案中)。

set _input=%* 
set params=!_input:%1 =! 
call OTHER_BATCH_FILE.cmd %params% 

當然,這是假定所有參數都不相同。

相關問題