2014-05-08 18 views
13

Tôi đang cố chuyển đổi tất cả dấu gạch chéo ngược() để chuyển tiếp dấu gạch chéo (/) trong một biến chứa tên tệp và vị trí. Tôi đã đọc về vấn đề này và thấy:Thay đổi dấu gạch chéo ngược để chuyển tiếp dấu gạch chéo trong tệp lô của cửa sổ

%variable:str1=str2% 

set "var=%var:\=/%" 

mà tôi đã cố gắng, nhưng tôi rõ ràng là không nhận được nó đúng.

Dưới đây là phần có liên quan của script .bat của tôi:

FOR %%f IN ("E:\myfiles\app1\data\*.csv") DO (
    echo %%f 
    set "f=%%f:\=/%" 
    echo %%f 
    echo.     
) 

Kết quả cho thấy mỗi tên tập tin liệt kê hai lần.

ví dụ: dòng này:

set "f=f:\=/%" 

không làm những gì tôi muốn nó. Ai có thể nhìn thấy những gì tôi đang làm sai?

+0

Câu hỏi này có cùng một giải pháp [Làm thế nào để bạn xác định tên người dùng trong upload ftp bởi một tập tin hàng loạt] (http://stackoverflow.com/questions/23535640/how-do-you-specify-the-username-in-ftp-upload-by-a-batch-file) – jeb

+0

Bạn có chắc chắn về giải pháp nằm trong câu hỏi bạn đã liên kết đến ? Tôi không thấy câu trả lời, và họ trông giống như những câu hỏi khác nhau với tôi. – user3253319

+0

Xin lỗi, bạn đã đúng. Ý tôi là [BATCH - Thay thế khoảng trống trong tên tệp với% 20 cho curl] (http://stackoverflow.com/questions/23538894/batch-replacing-spaces-in-filename-with-20-for-curl) – jeb

Trả lời

15

Trong một tuyên bố khối (a parenthesised series of statements), khối toàn bộ được phân tách và sau đó thực thi. Bất kỳ %var% trong khối sẽ được thay thế bằng giá trị của biến đó tại thời điểm khối được phân tích cú pháp - trước khi khối được thực hiện - điều tương tự cũng áp dụng cho một FOR ... DO (block).

Do đó, IF (something) else (somethingelse) sẽ được thực hiện bằng cách sử dụng các giá trị %variables% tại thời điểm IF gặp phải.

Hai cách phổ biến để khắc phục điều này là 1) để sử dụng setlocal enabledelayedexpansion và sử dụng !var! ở vị trí của %var% để truy cập giá trị thay đổi của var hoặc 2) để gọi một chương trình con để thực hiện tiếp tục xử lý bằng cách sử dụng các giá trị thay đổi.

Lưu ý do đó việc sử dụng CALL ECHO %%var%% hiển thị giá trị thay đổi là var.

Mã của bạn chứa hai biến riêng biệt được gọi là f.

Đầu tiên là điều khiển vòng lặp 'có thể biến đổi' được gọi là f và được tham chiếu bởi %%f.

Biến thứ hai là biến môi trường chung f được thiết lập theo tuyên bố set "f=...".Biến này có thể được truy cập bằng cách sử dụng %f%nhưng trong một block, nó sẽ xuất hiện để giữ lại giá trị của nó có khi kiểm soát for được phân tích cú pháp (trên thực tế, bất kỳ %var% được thay thế tại phân tích thời gian bởi giá trị của varở đó Hiện)

metavariables không thể được sử dụng trong báo cáo chuỗi thao tác như chuỗi con hoặc sản phẩm thay thế, chỉ có các biến môi trường chung có thể được sử dụng cho các hoạt động này, do đó bạn cần phải gán giá trị của metavariable f vào biến môi trường fsau đó thực hiện tác vụ thay thế chuỗi biến môi trường f.

Biến đổi, tất nhiên, là bạn phải sử dụng delayedexpansion và cú pháp !var! để truy cập giá trị được sửa đổi của biến môi trường trong một khối.

Vì vậy,

setlocal enabledelayedexpansion 
for...%%f...do (
    echo %%f 
    set "f=%%f" 
    set "f=!f:\=/!" 
    echo !f! 
) 
echo just for demonstration %f% !f! %%f 

này đặt giá trị của f theo cách thức yêu cầu (tất nhiên, bạn luôn có thể thay đổi tên để tránh nhầm lẫn ...)

Dòng cuối cùng chỉ đơn giản là để cho thấy giá trị cuối cùng được mua bởi f có thể được truy cập bên ngoài vòng lặp dưới dạng %f% hoặc !f! và rằng %%f nằm ngoài ngữ cảnh và được hiển thị là %f.

Một cách khác để làm điều này mà không delayedexpansion

for...%%f...do (
    echo %%f 
    set "f=%%f" 
    call set "f=%%f:\=/%%" 
    call echo %%f%% 
) 
echo just for demonstration %f% !f! %%f 

sự khác biệt là việc sử dụng các call và tăng gấp đôi % s, và dòng cuối cùng sẽ hiển thị !f! như điều đó - một chữ, vì ngoài delayedexpansion chế độ, ! chỉ là một ký tự khác không có ý nghĩa đặc biệt đối với cmd.

+1

wow, một lời giải thích rất toàn diện, cảm ơn rất nhiều! tôi đã phải đọc nó một vài lần, nhưng tôi nghĩ rằng tôi nhận được nó .. !! cửa sổ kịch bản hàng loạt vẫn trông thực sự kỳ lạ với tôi, tôi không chắc chắn tôi sẽ bao giờ thực sự "làm cho nó" – user3253319

+0

Tôi thực sự đã phải làm ngược lại: thay thế dấu gạch chéo phía trước với dấu gạch chéo ngược, nhưng lời giải thích của bạn là hoàn hảo. –

4

Điều này dường như làm việc cho tôi:

echo off 

setlocal enabledelayedexpansion 

FOR %%f IN ("C:\tools\workspace\*") DO (
    set old=%%f 
    echo !old! 
    set new=!old:\=/! 
    echo !new! 
    echo.     
) 

Sử dụng một biến riêng biệt chứ không phải là biến vòng lặp nên sự khác biệt, cùng với việc mở rộng cho phép trì hoãn như Syntex substittion biến bằng cách sử dụng vòng lặp biến %% f dosn' t dường như làm việc.

+0

rực rỡ, vâng hoạt động, chúc mừng! – user3253319

32

này sẽ thay đổi back-slashes để chuyển tiếp-chéo trong một biến:

set "variable=E:\myfiles\app1\data\*.csv" 
set "variable=%variable:\=/%" 
echo "%variable%" 
+0

Cảm ơn. Rất ngắn và dễ thương .. – user8162

+0

Câu trả lời này hoạt động hoàn toàn tốt mà không cần một vòng lặp. Tôi chỉ thử nó bản thân mình (tôi không cần báo giá, mặc dù). – ThePersonWithoutC

+2

Cảm ơn @ThePersonWithoutC - dấu ngoặc kép bảo vệ một số ký tự độc nhất định như '&' và chỉ làm cho nó mạnh mẽ hơn cho các tình huống kỳ lạ. – foxidrive

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