2008-09-02 25 views
154

Tôi có một tập hợp các tên tập tin cơ sở, cho mỗi tên 'f' có chính xác hai tập tin, 'f.in' và 'f.out'. Tôi muốn viết một tập tin thực thi (trong Windows XP) mà đi qua tất cả các tên tập tin, cho mỗi người cần:Cách lặp qua các tập tin khớp với ký tự đại diện trong tập tin thực thi

  • hiển thị tên cơ sở 'f'
  • Thực hiện một hành động trên 'f.in'
  • Thực hiện hành động khác trên 'f.out'

tôi không có cách nào để liệt kê các thiết lập của tên tập tin cơ sở, ngoài việc tìm kiếm * .in (hoặc * .out) ví dụ.

+7

Tôi thực sự không muốn trở thành anh chàng này sau 111/0 phiếu bầu, nhưng câu hỏi của bạn không hiển thị bất kỳ tìm kiếm lại nào. – Blauhirn

Trả lời

234

Giả sử bạn có hai chương trình xử lý hai tập tin, process_in.exe và process_out.exe:

for %%f in (*.in) do (
    echo %%~nf 
    process_in "%%~nf.in" 
    process_out "%%~nf.out" 
) 

%% ~ nf là công cụ sửa đổi thay thế, chỉ mở rộng% f thành tên tệp. Xem các công cụ sửa đổi khác trong https://technet.microsoft.com/en-us/library/bb490909.aspx (ở giữa trang) hoặc chỉ trong câu trả lời tiếp theo.

+28

Sử dụng một duy nhất '%' nếu gõ lệnh này trên dòng lệnh. Tôi biết OP không hỏi về dòng lệnh, nhưng đó là những gì tôi đang tìm kiếm khi câu hỏi này xuất hiện ở đầu tìm kiếm của Google của tôi. Những người khác có thể đánh giá cao chút này. – Jason

+1

Bạn có thể giải thích cú pháp không? Biến vòng lặp được khai báo '%% f' tại sao lại là' %% ~ nf' sau? –

+3

@ColonelPanic - có một số công cụ sửa đổi '~' để thực hiện mọi thứ, như trong ví dụ của tôi, chỉ cần lấy tên tệp. Chỉ là thói quen để tôi sử dụng nó trong trường hợp '*' thực hiện đường dẫn đầy đủ hay gì đó. Có một số các công cụ sửa đổi này (ở giữa trang): http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/batch.mspx?mfr=true –

4

Cách dễ nhất, như tôi thấy, là sử dụng vòng lặp for gọi một tệp lô thứ hai để xử lý, chuyển tên tệp thứ hai đó vào tên cơ sở.

Theo/cho? help, basename có thể được trích xuất bằng cách sử dụng tùy chọn nifty ~ n. Vì vậy, tập lệnh cơ sở sẽ đọc:

for %%f in (*.in) do call process.cmd %%~nf 

Sau đó, trong process.cmd, giả sử% 0 chứa tên cơ sở và hành động tương ứng. Ví dụ:

echo The file is %0 
copy %0.in %0.out 
ren %0.out monkeys_are_cool.txt 

Có thể có một cách tốt hơn để làm điều này trong một kịch bản, nhưng tôi đã luôn luôn là một chút mơ hồ về cách để kéo nhiều lệnh trong một duy nhất cho vòng lặp trong một tập tin thực thi.

EDIT: Thật tuyệt vời! Tôi đã bằng cách nào đó đã bỏ lỡ trang trong các tài liệu cho thấy rằng bạn có thể làm các khối nhiều dòng trong vòng lặp FOR. Tôi sẽ đi phải quay trở lại và viết lại một số tập tin batch bây giờ ...

3

Có một công cụ thường được sử dụng trong MS Servers (như xa như tôi có thể nhớ) gọi forfiles:

Các liên kết chứa trên trợ giúp cũng như liên kết tới trang tải xuống của microsoft.

68

Bạn có thể sử dụng dòng này để in các nội dung của máy tính để bàn của bạn:

FOR %%I in (C:\windows\desktop\*.*) DO echo %%I 

Một khi bạn đã biến %%I thật dễ dàng để thực hiện một lệnh trên nó (chỉ cần thay thế từ tiếng vang với chương trình của bạn)

Bên cạnh đó, thay thế cho tài liệu tham khảo biến đã được tăng cường Bây giờ bạn có thể sử dụng cú pháp tùy chọn sau đây:

%~I   - expands %I removing any surrounding quotes (") 
%~fI  - expands %I to a fully qualified path name 
%~dI  - expands %I to a drive letter only 
%~pI  - expands %I to a path only (directory with \) 
%~nI  - expands %I to a file name only 
%~xI  - expands %I to a file extension only 
%~sI  - expanded path contains short names only 
%~aI  - expands %I to file attributes of file 
%~tI  - expands %I to date/time of file 
%~zI  - expands %I to size of file 
%~$PATH:I - searches the directories listed in the PATH 
       environment variable and expands %I to the 
       fully qualified name of the first one found. 
       If the environment variable name is not 
       defined or the file is not found by the 
       search, then this modifier expands to the 
       empty string 


[https://ss64.com/nt/syntax-args.html][1] 

Trong các ví dụ trên %I và PATH có thể được thay thế bằng các giá trị hợp lệ khác. Cú pháp %~ được chấm dứt bằng tên biến FOR hợp lệ. Chọn các tên biến hoa chữ thường như %I làm cho nó dễ đọc hơn và tránh nhầm lẫn với các công cụ sửa đổi, không phân biệt chữ hoa chữ thường.

Bạn có thể nhận được đầy đủ tài liệu bằng cách gõ FOR /?

+0

Điều này dường như không hoạt động. '%% Tôi đã bất ngờ tại thời điểm này.' – Brad

+2

@Brad nếu bạn đang sử dụng điều này trong dòng lệnh (và không phải trong một tập tin thực thi), sau đó sử dụng'% I' thay vì '%% I' – doubleDown

3

Mở rộng trên Nathans bài đăng. Sau đây sẽ làm rất nhiều công việc trong một tập tin thực thi.

@echo off 

if %1.==Sub. goto %2 

for %%f in (*.in) do call %0 Sub action %%~nf 
goto end 

:action 
echo The file is %3 
copy %3.in %3.out 
ren %3.out monkeys_are_cool.txt 

:end 
0

Mã bên dưới lọc tên tệp bắt đầu bằng chuỗi con đã cho. Nó có thể được thay đổi để phù hợp với nhu cầu khác nhau bằng cách làm việc trên khai thác subfname chuỗi và NẾU tuyên bố:

echo off 
rem filter all files not starting with the prefix 'dat' 
setlocal enabledelayedexpansion 
FOR /R your-folder-fullpath %%F IN (*.*) DO (
set fname=%%~nF 
set subfname=!fname:~0,3! 
IF NOT "!subfname!" == "dat" echo "%%F" 
) 
pause 
0

Vang vọng f.in và f.out sẽ tách các khái niệm về những gì để lặp và những gì không để lặp khi được sử dụng trong một cho/f loop.

::Get the files seperated 
echo f.in>files_to_pass_through.txt 
echo f.out>>files_to_pass_through.txt 

for /F %%a in (files_to_pass_through.txt) do (
for /R %%b in (*.*) do (
if "%%a" NEQ "%%b" (
echo %%b>>dont_pass_through_these.txt 
) 
) 
) 
::I'm assuming the base name is the whole string "f". 
::If I'm right then all the files begin with "f". 
::So all you have to do is display "f". right? 
::But that would be too easy. 
::Let's do this the right way. 
for /f %%C in (dont_pass_through_these.txt) 
::displays the filename and not the extention 
echo %~nC 
) 

Mặc dù bạn không hỏi, một cách tốt để vượt qua các lệnh vào f.in và f.out sẽ được ...

for /F %%D "tokens=*" in (dont_pass_through_these.txt) do (
for /F %%E in (%%D) do (
start /wait %%E 
) 
) 

Một liên kết đến tất cả các lệnh Windows XP: link

Tôi xin lỗi nếu tôi không trả lời đúng. Câu hỏi rất khó cho tôi đọc.

Các vấn đề liên quan