我需要运行一个简单的find命令并将输出重定向到Windows批处理文件中的变量。
我试过这个:
set file=ls|find ".txt"
echo %file%
但它不起作用。
如果我运行此命令,它可以正常工作:
set file=test.txt
echo %file%
显然我的命令输出没有设置为我的变量。有人可以帮忙吗?感谢
答案 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"
的语法,但它无法处理命令中的管道,因此我将输出重定向到临时位置。
我强烈建议您考虑使用ls
或bash
或{{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.