Windows Batch帮助从命令输出设置变量

时间:2009-11-17 03:54:05

标签: batch-file

我需要运行一个简单的find命令并将输出重定向到Windows批处理文件中的变量。

我试过这个:

set file=ls|find ".txt"
echo %file%

但它不起作用。

如果我运行此命令,它可以正常工作:

set file=test.txt
echo %file%  

显然我的命令输出没有设置为我的变量。有人可以帮忙吗?感谢

8 个答案:

答案 0 :(得分:9)

我只是想知道如何在其中使用带管道的命令,这是我的命令(提取svn repo的头部修订版):

SET SVN_INFO_CMD=svn info http://mySvnRepo/MyProjects
FOR /f "tokens=1 delims=" %%i IN ('%SVN_INFO_CMD% ^| find "Revision"') DO echo %%i

答案 1 :(得分:6)

首先,在UNIX shell中,您似乎对您的问题的期望是不可能的。 shell应该如何知道ls|find foo是一个命令而test.txt不是?在这里执行什么?这就是UNIX shell为这些东西提供反击的原因。无论如何,我离题了。

您无法将环境变量设置为shell中的多行字符串。所以我们现在遇到了一个问题,因为ls的输出不太适合。

但你真正想要的是所有文本文件的列表,对吧?根据您的需要,这很容易做到。所有这些示例中的主要部分是for循环,迭代一组文件。

如果您只需要为每个文本文件执行操作:

for %%i in (*.txt) do echo Doing something with "%%i"

这甚至适用于带空格的文件名,并且不会错误地捕获名称中间只有.txt的文件,例如foo.txt.bar。只是要指出你的方法并不像你想要的那样漂亮。

无论如何,如果你想要一个文件列表,你可以使用一个小技巧来创建数组,或类似的东西:

setlocal enabledelayedexpansion
set N=0
for %%i in (*.txt) do (
    set Files[!N!]=%%i
    set /a N+=1
)

在此之后,您将拥有许多环境变量,名为Files[0]Files[1]等,每个变量都包含一个文件名。你可以用

循环它
for /l %%x in (1,1,%N%) do echo.!Files[%%x]!

(请注意,我们在这里输出了一条多余的新行,我们可以删除它,但需要多行代码: - )

如果您愿意,可以构建一长串文件名。您可能会认识到这种模式:

setlocal enabledelayedexpansion
set Files=
for %%i in (*.txt) do set Files=!Files! "%%i"

现在我们有一个很长的文件名行。随心所欲地使用它。这有时很方便将一堆文件传递给另一个程序。

请注意,批处理文件的最大行长度约为8190个字符。因此,这限制了您可以在一行中拥有的数量。是的,在一行中枚举一大堆文件可能会在这里溢出。

回到原点,批处理文件无法捕获命令输出。其他人之前已经注意到了。您可以将for /f用于此目的:

for /f %%i in ('dir /b') do ...

这将迭代命令返回的行,沿途标记它们。不像反叛者那样方便,但足够接近并足以满足大多数目的。

默认情况下,令牌会在空格处分解,因此如果您有一个文件名“Foo bar”,那么突然您在%%i中只有“Foo”而在%%j中只有“bar”。这可能令人困惑,而这些事情是您不想仅仅使用for /f获取文件列表的主要原因。

如果与某些程序参数发生冲突,您也可以使用反引号代替撇号:

for /f "usebackq" %%i in (`echo I can write 'apostrophes'`) do ...

请注意,这也是令人信服的。您可以提供更多选项。它们在help for命令中详细说明。

答案 2 :(得分:3)

set命令有/p选项,告诉它从标准输入读取值。不幸的是,它不支持管道,但它支持从现有文件的第一行读取值。

因此,要将变量设置为第一个*.txt文件的名称,您可以执行以下操作:

dir /b *.txt > filename.tmp
set /p file=< filename.tmp
del /q filename.tmp

重要的是不要在=之前或之后添加空格。

P上。 S. No for s,no tokens

答案 3 :(得分:1)

这是一个批处理文件,它将返回find输出的最后一项:

@echo off

ls | find ".txt" > %temp%\temp.txt
for /f %%i in (%temp%\temp.txt) do set file=%%i
del %temp%\temp.txt
echo %file%

for具有解析命令输出for /f "usebackq"的语法,但它无法处理命令中的管道,因此我将输出重定向到临时位置。

我强烈建议您考虑使用lsbash或{{1 }}。即使python也会比cmd脚本提高20倍。

答案 4 :(得分:1)

简短的回答是:不要!

Windows shell env var最多可以保存32 Kb,保存程序中的输出是不安全的。 这就是你无法做到的原因。在批处理脚本中,您必须采用其他编程风格。如果你需要所有的输出 从程序然后将其保存到文件。如果您只需要检查某些属性,那么将输出管道输入 执行检查并使用errorlevel机制的程序:

@echo off

type somefile.txt | find "somestring" >nul
if %errorlevel% EQU 1 echo Sorry, not found!
REM Alternatively:
if errorlevel 1 echo Sorry, not found!

然而,使用逻辑运算符Perl样式更优雅:

@echo off

(type somefile.txt | find "somestring" >nul) || echo Sorry, not found!

答案 5 :(得分:0)

它在DOS中不可用,但在Windows控制台中,有for命令。只需在命令提示符下键入“help for”即可查看所有选项。要设置单个变量,您可以使用它:

for /f %%i in ('find .txt') do set file=%%i

请注意,这仅适用于从'find .txt'返回的第一行,因为默认情况下,Windows只会扩展一次变量。您必须启用延迟展开,如here所示。

答案 6 :(得分:0)

你实际上在做的是列出.txt文件。有了它,你可以使用for循环来覆盖dir cmd 例如

for /f "tokens=*" %%i in ('dir /b *.txt') do set file=%%i

或者如果您更喜欢使用ls,则无需管道查找。

for /f "tokens=*" %%i in ('ls *.txt') do set file=%%i

答案 7 :(得分:0)

从命令输出设置变量的示例:

FOR /F "usebackq" %%Z IN ( `C:\cygwin\bin\cygpath "C:\scripts\sample.sh"` ) DO SET BASH_SCRIPT=%%Z

c:\cygwin\bin\bash -c '. ~/.bashrc ; %BASH_SCRIPT%'

另外,请注意,如果要在DOS shell中测试FOR命令,则只需要使用%Z而不是%% Z,否则会出现以下错误:

%%Z was unexpected at this time.