2013-02-19 25 views
39

Bạn có thể chuyển hướng đầu ra của lệnh đến biến bằng đường ống không?Đặt đầu ra của lệnh dưới dạng biến (có đường ống)

tôi đã không cố gắng nhiều như tôi đã không thể nghĩ về bất cứ điều gì để cố gắng, nhưng tôi đã cố gắng một phương pháp (với hai biến thể) ...

Ví dụ:

echo Hello|set text= 

đã không làm việc, không phải đã làm:

echo Hello | set text= 

tôi biết bạn có thể làm điều đó khá dễ dàng với lệnh FOR, nhưng tôi nghĩ rằng nó sẽ trông "đẹp hơn" với một ống.

Và nếu bạn đang băn khoăn, tôi không có lý do cụ thể nào tôi hỏi điều này ngoài việc tôi tò mò và tôi không thể tìm thấy câu trả lời.

+1

Kiểm tra Dolphy ở đây: http://stackoverflow.com/questions/6359820/batch-files-how-to-set- lệnh-đầu ra-as-a-biến - nếu bạn thực sự không muốn sử dụng cho bạn có thể sử dụng một tập tin tạm thời. Không có cách nào để làm điều đó với một đường ống, mặc dù. – Vicky

+1

Sự cố này được mô tả chi tiết tại đây: http: // stackoverflow.com/questions/8192318/tại sao-không-trì hoãn-mở rộng-thất bại-khi-bên trong-một-piped-block-of-mã số – Aacini

+0

http://superuser.com/a/1007898/429721 hoàn thiện cho đường ống, stdout/err chuyển hướng, nhiều thực thi, lưu trữ đầu ra và xử lý giá trị như số và thao tác khác ... hoạt động khá tốt .. –

Trả lời

38

Cách của bạn không thể hoạt động vì hai lý do.

Bạn cần sử dụng set /p text= để đặt biến với nhập người dùng.
Vấn đề khác là đường ống.
Một đường ống bắt đầu hai trường hợp cmd.exe không đồng bộ và sau khi hoàn thành công việc cả hai trường hợp được đóng lại.

Đó là nguyên nhân tại sao dường như các biến không được đặt, nhưng một ví dụ nhỏ cho thấy rằng chúng được đặt nhưng kết quả bị mất sau này.

set myVar=origin 
echo Hello | (set /p myVar= & set myVar) 
set myVar 

Đầu ra

Hello 
origin 

Alternatives: Bạn có thể sử dụng cho vòng lặp để có được giá trị vào biến hoặc cũng tạo các file tạm.

for /f "delims=" %%A in ('echo hello') do set "var=%%A" 
echo %var% 

hoặc

>output.tmp echo Hello 
>>output.tmp echo world 

<output.tmp (
    set /p line1= 
    set /p line2= 
) 
echo %line1% 
echo %line2% 
+3

Vì vậy, không có cách nào xung quanh các giới hạn mà không có một tệp tạm thời hoặc lệnh "cho"? Ngay cả khi không có, cảm ơn anyway. –

+0

Rõ ràng bạn có thể sử dụng 'FOR' nhưng sau đó bạn không cần một đường ống. Cùng áp dụng cho các tập tin tạm thời – jeb

+1

btw, nó xuất hiện trong các thử nghiệm của tôi mà bạn chỉ có thể sử dụng 1 lệnh trong một câu lệnh for. Bạn không thể chuỗi các lệnh khác cùng với &. –

2

Trong một tập tin batch Tôi thường tạo ra một tập tin trong thư mục tạm và đầu ra append từ một chương trình, sau đó tôi gọi nó là với một tên biến để thiết lập biến . Như thế này:

:: Create a set_var.cmd file containing: set %1= 
set /p="set %%1="<nul>"%temp%\set_var.cmd" 

:: Append output from a command 
ipconfig | find "IPv4" >> "%temp%\set_var.cmd" 
call "%temp%\set_var.cmd" IPAddress 
echo %IPAddress% 
+1

Khá khéo léo. Thông thường, tránh các tập tin tạm thời là tốt đẹp, mặc dù. – zanlok

11

Việc thiếu một backtick/backquote cơ sở Linux như là một ít phiền toái lớn của thế giới trước PowerShell. Sử dụng backquotes thông qua for-loops không phải là ở tất cả các ấm cúng. Vì vậy, chúng ta cần một lệnh của setvar myvar cmd-line.

Trong số %path% Tôi có một thư mục với một số thùng và lô để đối phó với những thiếu sót trong Win đó.

Một loạt tôi đã viết là:

:: setvar varname cmd 
:: Set VARNAME to the output of CMD 
:: Triple escape pipes, eg: 
:: setvar x dir c:\ ^^^| sort 
:: ----------------------------- 

@echo off 
SETLOCAL 

:: Get command from argument 
for /F "tokens=1,*" %%a in ("%*") do set cmd=%%b 

:: Get output and set var 
for /F "usebackq delims=" %%a in (`%cmd%`) do (
    ENDLOCAL 
    set %1=%%a 
) 

:: Show results 
SETLOCAL EnableDelayedExpansion 
echo %1=!%1! 

Vì vậy, trong trường hợp của bạn, bạn nên gõ:

> setvar text echo Hello 
text=Hello 

Kịch bản thông báo cho bạn về những kết quả, điều đó có nghĩa bạn có thể:

> echo text var is now %text% 
text var is now Hello 

Bạn có thể sử dụng bất kỳ lệnh nào:

> setvar text FIND "Jones" names.txt 

Điều gì sẽ xảy ra nếu lệnh bạn muốn chuyển vào một số biến chứa chính đường ống?
Ba thoát nó, ^^^|:

> setvar text dir c:\ ^^^| find "Win" 
+0

Phần 'usebackq delims =' làm gì? –

+1

@RichardLeMesurier: 'usebackq' chỉ định sử dụng ngữ nghĩa giống như Linux, trong đó chuỗi được trích dẫn sau được thực thi dưới dạng lệnh và đầu ra được phân tích thành các biến' for' (ở đây '%% a'). 'delims = x' chỉ định dấu phân tách được sử dụng trong phân tích cú pháp (ở đây không có dấu phân tách). – antonio

+0

Thx để làm rõ. Tôi đã sử dụng mẫu này để thành công lớn trong công cụ xây dựng. Câu trả lời này phải là câu trả lời được chấp nhận. –

3

NÀY KHÔNG SỬ DỤNG đường ống, nhưng đòi hỏi một tempfile đơn
Tôi sử dụng này để đưa timestamps đơn giản hóa thành một batfile lowtech bảo trì hàng ngày

Chúng tôi đã có trong ngắn đã định dạng Hệ thống-Thời gian thành HHmm của chúng tôi, (là 2245 cho 10:45 PM)
Tôi xuất trực tiếp của Maint-Routines thành logfiles với dấu thời gian $ DATE% @% TIME%;
. . . nhưng% TIME% là một chuỗi xấu xí dài (ví dụ: 224.513,56, cho xuống đến phần trăm của một giây.)

GIẢI PHÁP TỔNG QUAN:
1. Sử dụng chuyển hướng (">") để gửi lệnh "TIME/T" mọi ghi đè lên một tempfile trong thư mục% TEMP% DIRECTORY
2. Sau đó sử dụng tempfile rằng như đầu vào để thiết lập một biến mới (tôi gọi nó NOW)
3. Thay thế

echo $DATE%@%TIME% blah-blah-blah >> %logfile%
      với
echo $DATE%@%NOW% blah-blah-blah >> %logfile%


==== KHÁC BIỆT TRONG ĐẦU RA:
TRƯỚC:
SUCCESSFUL TIMESYNCH [email protected]
SAU:
SUCCESSFUL TIMESYNCH [email protected]


THỰC TẾ Mã sản phẩm:

TIME /T > %TEMP%\DailyTemp.txt 
SET /p NOW=<%TEMP%\DailyTemp.txt 
echo $DATE%@%NOW% blah-blah-blah >> %logfile%


hậu quả:
Tất cả những gì còn lại sau đó là logfile nối, và tempfile liên tục ghi đè. Và nếu Tempfile đã từng bị xóa, nó sẽ được tạo lại khi cần thiết.

+0

Đây thực sự là giải pháp duy nhất hoạt động khi tôi cố gắng chuyển một lệnh git phức tạp, ví dụ: 'git log --pretty = format:% ad_commit_% h -n 1 --date = short'. –

+0

Đơn giản và hiệu quả –

-1

Bạn có thể đặt đầu ra thành tệp tạm thời và đọc dữ liệu từ tệp sau đó bạn có thể xóa tệp tạm thời.

echo %date%>temp.txt 
set /p myVarDate= < temp.txt 
echo Date is %myVarDate% 
del temp.txt 

Trong biến này "myVarDate" chứa đầu ra của lệnh

câu trả lời
+3

Đã có 3 câu trả lời cũ đề cập đến một tempfile. Tôi không thể thấy thêm bất kỳ lợi ích nào của câu trả lời của bạn? – jeb

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