1

我正在尝试完成以下荒谬的任务:

我有一个包含一组完全限定文件名的文本文件。我想遍历文件并将每一行附加到一个公共变量,该变量可以传递给命令行工具。例如,该文件可能是:

C:\dir\test.txt

C:\WINDOWS\test2.txt

C:\text3.txt

我想将它们分配给一些变量'a',这样:

a = "C:\dir\test.txt C:\WINDOWS\test2.txt C:\text2.txt"

第二个问题是 - 什么是好的批处理文件参考?我在 Windows 资料和许多本土网站中找到了一些东西,但没有什么特别完整的。

4

4 回答 4

9

至于参考资料,SS64.com也不错。Rob van der Woude也经常被联系起来。


至于你的问题,这很简单:

@echo off
setlocal enableextensions enabledelayedexpansion

set LIST=
for /f %%x in (yourfile.txt) do (
    set LIST=!LIST! "%%x"
)

echo %LIST%

endlocal

更深入的解释:

setlocal enableextensions enabledelayedexpansion

我们在这里启用延迟扩展。这是至关重要的,否则我们将无法在随后的for循环中操作文件列表。

for /f %%x in (yourfile.txt) do (
    set LIST=!LIST! "%%x"
)

for /f遍历文件中的行,这正是我们需要的。在每次循环迭代中,我们将下一行附加到LIST变量中。注意使用 of!LIST!而不是通常的%LIST%. 这表示扩展延迟,并确保每次运行此命令时都会重新评估变量。

通常cmd在读取和解析一行后立即将变量扩展为它们的值。对于cmd单行来说,要么是一行,要么是所有算作一行的东西,这恰好适用于由括号分隔的块,就像我们在这里使用的那样。因此,cmd对于完整的块来说,无论循环内部运行的频率如何,它都会被读取和解析一次。

如果我们在%LIST%这里使用而不是!LIST!then 变量将立即被其值替换(此时为空),循环将如下所示:

for /f %%x in (yourfile.txt) do (
    set LIST= "%%x"
)

显然这不是我们想要的。延迟扩展确保仅在真正需要其值时才扩展变量。在这种情况下,当循环内部运行并构造文件名列表时。

之后变量%LIST%!LIST!(现在使用哪个不再重要)包含文件中的行列表。

有趣的是,该set命令的帮助正好包括这个延迟扩展的例子:

最后,添加了对延迟环境变量扩展的支持。默认情况下始终禁用此支持,但可以通过 /V 命令行开关到 CMD.EXE 启用/禁用。见 CMD /?

延迟的环境变量扩展对于绕过当前扩展的限制很有用,这种限制发生在读取一行文本时,而不是在执行时。以下示例演示了立即变量扩展的问题:

set VAR=before
if "%VAR%" == "before" (
    set VAR=after
    if "%VAR%" == "after" @echo If you see this, it worked
)

永远不会显示该消息,因为 BOTH IF 语句中的 %VAR% 在读取第一个 IF 语句时被替换,因为它在逻辑上包括 IF 的主体,这是一个复合语句。因此,复合语句中的 IF 实际上是将“之前”与“之后”进行比较,这永远不会相等。同样,以下示例将无法按预期工作:

set LIST=
for %i in (*) do set LIST=%LIST% %i
echo %LIST%

因为它不会在当前目录中建立文件列表,而是将 LIST 变量设置为找到的最后一个文件。同样,这是因为在读取 FOR 语句时 %LIST% 只扩展了一次,而此时 LIST 变量为空。所以我们正在执行的实际 FOR 循环是:

for %i in (*) do set LIST= %i

它只是将 LIST 设置为找到的最后一个文件。

延迟环境变量扩展允许您在执行时使用不同的字符(感叹号)来扩展环境变量。如果启用了延迟变量扩展,则上述示例可以编写如下以按预期工作:

set VAR=before
if "%VAR%" == "before" (
    set VAR=after
    if "!VAR!" == "after" @echo If you see this, it worked
)

set LIST=
for %i in (*) do set LIST=!LIST! %i
echo %LIST%
于 2009-09-30T20:53:10.407 回答
0

你所追求的可以用FOR /F 命令来完成。

这是我用过很多次的好资源:

http://www.robvanderwoude.com/batchfiles.php

于 2009-09-30T20:53:02.153 回答
0

一本好书:Tim Hill 的 Windows NT Shell Scripting。我的版本是 1998 年发布的,但它仍然适用于 Windows 2008 中的 Windows 命令程序。

于 2009-09-30T20:58:08.487 回答
0
type *commonfilepart* >> concat_result_file

操作系统:WINDOWS 服务器 2003

于 2010-06-01T13:42:13.447 回答