首先,您对问题的期望似乎在 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 命令中有详细说明。