58

コマンドの出力をパイプで変数にリダイレクトできますか?

試してみることが思いつかなかったのであまり試していませんが、1つの方法(2つのバリエーションで)を試しました...

例えば:

echo Hello|set text=

うまくいきませんでした:

echo Hello | set text=

コマンドでかなり簡単にできることは知っていますがFOR、パイプを使用すると「見栄えが良く」なると思います。

疑問に思われているかもしれませんが、興味があり、答えが見つからないということ以外に、これを尋ねている特定の理由はありません。

4

6 に答える 6

54

あなたのやり方は2つの理由でうまくいきません。

ユーザー入力set /p text=で変数を設定するために使用する必要があります。 もう一つの問題はパイプです。 パイプは2つの非同期cmd.exeインスタンスを開始し、ジョブの終了後に両方のインスタンスを閉じます。

これが、変数が設定されていないように見える原因ですが、小さな例では、変数は設定されているが、結果は後で失われます。

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

出力

Hello
origin

代替方法: FORループを使用して、値を変数または一時ファイルに取得できます。

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

また

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

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

マクロによる代替:

バッチマクロを使用できます。これは、bashに相当するものに少し似ています。

@echo off

REM *** Get version string 
%$set% versionString="ver"
echo The version is %versionString[0]%

REM *** Get all drive letters
`%$set% driveLetters="wmic logicaldisk get name /value | findstr "Name""
call :ShowVariable driveLetters

マクロの定義は、
SO:MSバッチファイルを使用したプログラムの出力の変数への割り当てにあります。

于 2013-02-19T19:09:15.193 に答える
15

Linux のようなバックティック/バッククォート機能がないことは、PowerShell 以前の世界の大きな悩みの種です。for ループを介して逆引用符を使用するのは、まったく快適ではありません。そのため、ちょっとしたsetvar myvar cmd-lineコマンドが必要です。

私の%path%中には、これらのWinの欠点に対処するために、多数のビンとバッチを含むディレクトリがあります。

私が書いた1つのバッチは次のとおりです。

:: 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! 

したがって、あなたの場合、次のように入力します。

> setvar text echo Hello
text=Hello 

スクリプトによって結果が通知されます。これは、次のことができることを意味します。

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

どんなコマンドでも使用できます:

> setvar text FIND "Jones" names.txt

ある変数にパイプしたいコマンド自体にパイプが含まれている場合はどうなるでしょうか?
トリプルエスケープ、^^^|:

> setvar text dir c:\ ^^^| find "Win"
于 2014-09-20T23:30:49.547 に答える
5

これは PIPE を使用しませんが、単一の一時ファイルが必要
です これを使用して、簡略化されたタイムスタンプをローテクの毎日のメンテナンス バットファイルに入れました

システム時間を HHmm にショートフォーマットしました (午後 10 時 45 分の場合は 2245)
直接出力します$DATE%@%TIME% タイムスタンプを持つログファイルへの Maint-Routine の。
. . . しかし、 %TIME% は長く醜い文字列です (例: 224513.56、100 分の 1 秒まで)

解決策の概要:
1. リダイレクション (">") を使用してコマンド "TIME /T" を毎回送信し、%TEMP% DIRECTORY 内の一時ファイルを上書きします
。 2. 次に、その一時ファイルを入力として使用して新しい変数 (I 3.
交換する

echo $DATE%@%TIME% 何とか何とか >> %logfile%
      と
echo $DATE%@%NOW% 何とか何とか >> %logfile%


====出力の違い:
前:
成功した TIMESYNCH 29Dec14@222552.30
後:
成功した TIMESYNCH 29Dec14@2252


実際のコード:

時刻 /T > %TEMP%\DailyTemp.txt
SET /p NOW=<%TEMP%\DailyTemp.txt
echo $DATE%@%NOW% 何とか何とか >> %logfile%


AFTERMATH:
その後に残るのは、追加されたログ ファイルと、常に上書きされる一時ファイルだけです。また、Tempfile が削除された場合は、必要に応じて再作成されます。

于 2014-12-30T06:20:06.807 に答える
2

バッチ ファイルでは、通常、一時ディレクトリにファイルを作成し、プログラムからの出力を追加してから、変数名を付けて呼び出し、その変数を設定します。このような:

:: 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%
于 2014-07-24T11:57:02.697 に答える