Windows XP批处理文件连接

发布于 2024-08-06 22:20:56 字数 374 浏览 4 评论 0原文

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

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

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 材料和许多本土网站中找到了一些东西,但没有什么特别完整的。

I'm trying to accomplish the following ridiculous task:

I have a text file containing a set of fully qualified filesnames. I want to iterate through the file and append each line to a common variable, that can be passed to a command line tool. For example, the file might be:

C:\dir\test.txt

C:\WINDOWS\test2.txt

C:\text3.txt

and I'd like to assign them to some variable 'a' such that:

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

A secondary question is - what is a good batch file reference? I'm finding some stuff in the Windows material, and a lot of home-grown websites, but nothing particularly complete.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

旧人 2024-08-13 22:20:56

至于参考,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 变量中。请注意使用 !LIST! 而不是通常的 %LIST%。这表示延迟扩展并确保每次运行此命令时都会重新评估变量。

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

如果我们在这里使用 %LIST% 而不是 !LIST!,那么该变量将立即被其值替换(此时为空),并且循环将具有看起来像这样:

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

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

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

有趣的是,set 命令的帮助正是包含这个延迟扩展的示例:

最后,支持延迟
环境变量扩展有
已添加。这种支持永远是
默认情况下禁用,但可能会
通过 /V 命令启用/禁用
线路切换到 CMD.EXE。参见 CMD /?

延迟环境变量扩展
对于绕过
当前扩张的局限性
当一行文本出现时会发生这种情况
读取,而不是执行时。这
下面的例子演示了
立即变量的问题
扩展:

设置 VAR=之前
如果“%VAR%”==“之前”(
    设置VAR=之后
    if "%VAR%" == "after" @echo 如果你看到这个,它就起作用了
)

永远不会显示该消息,因为
两个 IF 语句中的 %VAR% 是
当第一个 IF 被替换
语句被读取,因为它在逻辑上
包括 IF 的主体,即
复合语句。所以如果
复合语句里面是
真正比较“之前”和“之后”
这永远不会相等。相似地,
以下示例将不起作用
预期:

<前><代码>设置列表=
对于 (*) 中的 %i,请设置 LIST=%LIST% %i
回显%列表%

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

对于 (*) 中的 %i 设置 LIST= %i

它只是不断地将 LIST 设置为
最后找到的文件。

延迟环境变量扩展
允许您使用不同的
字符(感叹号)到
展开环境变量
执行时间。如果延迟变量
扩展已启用,以上
例子可以写成如下
按预期工作:

设置 VAR=之前
如果“%VAR%”==“之前”(
    设置VAR=之后
    如果“!VAR!” ==“after”@echo 如果你看到这个,它就起作用了
)

设置列表=
对于 (*) 中的 %i,请设置 LIST=!LIST! %我
回显%列表%

As for references, SS64.com isn't bad. Rob van der Woude gets linked fairly often, too.


As for your problem, that's easy:

@echo off
setlocal enableextensions enabledelayedexpansion

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

echo %LIST%

endlocal

More in-depth explanation:

setlocal enableextensions enabledelayedexpansion

We're enabling delayed expansion here. This is crucial as otherwise we wouldn't be able to manipulate the list of files within the for loop that follows.

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

for /f iterates over lines in a file, so exactly what we need here. In each loop iteration we append the next line to the LIST variable. Note the use of !LIST! instead of the usual %LIST%. This signals delayed expansion and ensures that the variable gets re-evaluated every time this command is run.

Usually cmd expands variables to their values as soon as a line is read and parsed. For cmd a single line is either a line or everything that counts as a line, which happens to hold true for blocks delimited by parentheses like the one we used here. So for cmd the complete block is a single statement which gets read and parsed once, regardless of how often the interior of the loop runs.

If we would have used %LIST% here instead of !LIST! then the variable would have been replaced immediately by its value (empty at that point) and the loop would have looked like this:

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

Clearly this isn't what we wanted. Delayed expansion makes sure that a variable is expanded only when its value is really needed. In this case when the interior of the loop runs and constructs a list of file names.

Afterwards the variable %LIST% or !LIST! (now it doesn't really matter anymore which to use) contains the list of lines from the file.

Funnily enough, the help for the set command includes exactly this example for delayed expansion:

Finally, support for delayed
environment variable expansion has
been added. This support is always
disabled by default, but may be
enabled/disabled via the /V command
line switch to CMD.EXE. See CMD /?

Delayed environment variable expansion
is useful for getting around the
limitations of the current expansion
which happens when a line of text is
read, not when it is executed. The
following example demonstrates the
problem with immediate variable
expansion:

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

would never display the message, since
the %VAR% in BOTH IF statements is
substituted when the first IF
statement is read, since it logically
includes the body of the IF, which is
a compound statement. So the IF
inside the compound statement is
really comparing "before" with "after"
which will never be equal. Similarly,
the following example will not work as
expected:

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

in that it will NOT build up a list of
files in the current directory, but
instead will just set the LIST
variable to the last file found.
Again, this is because the %LIST% is
expanded just once when the FOR
statement is read, and at that time
the LIST variable is empty. So the
actual FOR loop we are executing is:

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

which just keeps setting LIST to the
last file found.

Delayed environment variable expansion
allows you to use a different
character (the exclamation mark) to
expand environment variables at
execution time. If delayed variable
expansion is enabled, the above
examples could be written as follows
to work as intended:

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%
陌若浮生 2024-08-13 22:20:56

您可以使用 FOR /F 命令来完成您想要的操作。

这是我多次使用的好资源:

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

What you're after can be done with a FOR /F command.

Here's a good resource I've used many times:

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

夏尔 2024-08-13 22:20:56

一本好书:Tim Hill 的《Windows NT Shell 脚本》。我的版本是 1998 年发布的,但它对于 Windows 2008 中的 Windows 命令程序仍然有效。

A good book: Windows NT Shell Scripting by Tim Hill. The edition I have was published in 1998 but it is still valid for Windows command programs in Windows 2008.

暖伴 2024-08-13 22:20:56
type *commonfilepart* >> concat_result_file

操作系统:Windows Server 2003

type *commonfilepart* >> concat_result_file

OS: WINDOWS SERVER 2003

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文