2009-06-01 34 views
25

trùng lặp:thông số hàng loạt: tất cả mọi thứ sau% 1

Làm rõ: tôi biết các phương pháp lặp - điều này làm việc ngay cả trước khi lệnh Extensions; Tôi đã hy vọng cho một cái gì đó vui vẻ và không có giấy tờ như% ~ * 1 hoặc bất cứ điều gì - giống như những tài liệu tại http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/percent.mspx?mfr=true.


Trong một tập tin thực thi Windows (với cái gọi là "Command Extensions" trên),% 1 là số đầu tiên,% 2 là lần thứ hai, vv% * là tất cả đối số nối vào nhau.

Câu hỏi của tôi: có cách nào để nhận mọi thứ SAU% 2 chẳng hạn?

Tôi không thể tìm thấy một điều như vậy, và nó sẽ hữu ích cho một cái gì đó tôi đang làm việc trên.

Trả lời

14

Tôi không chắc chắn nếu có lệnh trực tiếp nhưng bạn luôn có thể sử dụng vòng lặp đơn giản và thay đổi để nhận kết quả trong biến. Một cái gì đó như:

 
@echo off 
set RESTVAR= 
shift 
:loop1 
if "%1"=="" goto after_loop 
set RESTVAR=%RESTVAR% %1 
shift 
goto loop1 

:after_loop 
echo %RESTVAR% 

Hãy cho tôi biết nếu điều đó có ích!

+0

ok không nhận thấy rằng người khác đã trả lời nó đã là – Samuel

+0

Có, nhưng câu trả lời của bạn là đầy đủ nhất và là những gì tôi đã làm cuối cùng. – noamtm

+3

Có một vấn đề nhỏ với câu trả lời này - 'RESTVAR' sẽ chứa một không gian hàng đầu. Đây là một phiên bản tốt hơn một chút http://stackoverflow.com/a/761658/1488656 – Livven

5

Bạn có thể sử dụng SHIFT cho mục này. Nó loại bỏ% 1 và thay đổi tất cả các đối số khác thấp hơn. Tập lệnh này xuất tất cả các đối số sau% 2 (vì vậy nó xuất ra% 3,% 4 ...) cho đến khi một trong số đó rỗng (vì vậy nó là số cuối cùng):

@echo off 

SHIFT 
SHIFT 

:loop 
if "%1" == "" goto end 
echo %1 
SHIFT 
goto loop 

:end 

EDIT: Removed example using% * vì điều này không hoạt động -% * luôn luôn xuất ra tất cả các tham số

+0

Cũng giống như trong sh? Tuyệt quá! +1. Bạn có biết tùy chọn powershell là gì không? – OscarRyz

+0

Rất tiếc, chưa sử dụng PowerShell. – schnaader

1

Xây dựng trên câu trả lời của schnaader, tôi nghĩ điều này sẽ xảy ra nếu bạn muốn mọi thứ sau% 1 nối.

@echo off 

SHIFT 

set after1= 

:loop 
if "%1" == "" goto end 
set after1=%after1% %1 
SHIFT 
goto loop 


:end 

echo %after1% 
21

Có một giải pháp ngắn (one-liner) sử dụng các khả năng tokenization của for vòng:

:: all_but_first.bat 
echo all: %* 
for /f "tokens=1,* delims= " %%a in ("%*") do set ALL_BUT_FIRST=%%b 
echo all but first: %ALL_BUT_FIRST% 

đầu ra:

> all_but_first.bat foo bar baz 
all: foo bar baz 
all but first: bar baz 
+1

Đối với 'all-but-n', thay thế 'mã thông báo = 1' với' mã thông báo = n'. Các đối số còn lại sẽ vẫn ở trong '%% b' – CJxD

+0

Trong một số trường hợp, bạn có thể cần phải sử dụng! ALL_BUT_FIRST! thay vì% ALL_BUT_FIRST% (ví dụ nếu bạn đang ở trong một số vòng lặp khác); xem http://stackoverflow.com/questions/12423238/windows-cmd-set-within-for-loop-is-not-working – FremyCompany

+0

Đừng quên sử dụng 'setlocal enabledelayedexpansion' nếu bạn đang làm việc với'! var! '. –

3

Sau đây sẽ làm việc cho args với ", =, ' ' (so với câu trả lời @MaxTruxa)

echo %* 
set _all=%* 
call set _tail=%%_all:*%2=%% 
set _tail=%2%_tail% 
echo %_tail% 

Kiểm tra

> get_tail.cmd "first 1" --flag="other options" --verbose 
"first 1" --flag="other options" --verbose 
--flag="other options" --verbose 
+0

Tôi thực sự muốn có một phiên bản ELI5 của dòng CALL SET đó. –

+1

[Sử dụng nâng cao: GỌI lệnh nội bộ] (https://ss64.com/nt/call.html#advanced). Nó hoạt động như 'setlocal EnableDelayedExpansion' +' set _tail =! _ All: *% 2 =! '. –

+0

Nó sẽ thất bại trên này: get_tail.cmd -s -s arg1 –

1

Sau đây sẽ làm việc cho args bằng ", =, ''. Dựa trên câu trả lời của Dmitry Sokolov. Cố định vấn đề khi arg thứ hai là giống như arg đầu tiên.

@echo off 
echo %* 
set _tail=%* 
call set _tail=%%_tail:*%1=%% 
echo %_tail% 
Các vấn đề liên quan