在Windows批处理文件中的“for”命令中读取空值

3
我有一个与Windows中“for”批处理命令有关的问题。 我有一个名为keys.txt的文件,其中包含以下行 ..
key,value,x86,windows7
我想解析这一行并将4个以逗号分隔的变量存储在4个变量中。我通过以下Windows批处理脚本实现了这一点。
 for /F "tokens=1,2,3,4* delims=," %%i
 in (keys.txt) do (

    echo first is %%i

    echo second is %%j

    echo third is %%k

    echo fourth is %%l

    echo rest is %%m

    echo -------------  

 )

然而,当我修改keys.txt为

key,value,,windows7

第三个变量被打印为windows7。我本应该期望第三个变量为空,第四个变量为windows7。如果我在两个逗号之间加一个空格,像这样

key,value, ,windows7

那么它会将第三个变量打印为空,第四个变量为Windows7。
有人知道如何使先前的情况(即不带空格的情况)也能正确工作吗?

为什么要使用批处理来解析文件?你有其他选项吗?比如使用真正的文件解析器(语言)?如果无法下载和使用相关工具,可以使用VBScript,这在执行此类任务时更为优秀。 - ghostdog74
实际上,有很多用批处理脚本编写的代码,因此将整个代码迁移到vbs将是一项巨大的任务。但是,我找到了另一个选择,那就是编写一个vbs文件,创建一个带有一系列var=value行的文件,然后从父批处理文件中调用这个批处理文件。 - Santhosh
2个回答

4
尝试这个。灵感来自这里
脚本会预处理每一行,将文本#NUL#分配给每个空槽。在此之后,您可以忽略#NUL#的值。
cls
setlocal enabledelayedexpansion
@echo off
for /f "tokens=*" %%X in (keys.txt) do (
    set "work=%%X"
    :: fill empty fields with "#NUL#" ...
    :: but do it twice, just in case consecutive fields are empty
    for /l %%i in (1,1,2) do set "work=!work:,,=,#NUL#,!"
    for /F "tokens=1,2,3,4* delims=," %%i in ("!work!") do (
echo first is %%i
echo second is %%j
echo third is %%k
echo fourth is %%l
echo rest is %%m
echo -------------  
))

HTH


1

for 的设计在某些系统上不会保留空/空白标记,所以将下一个标记分配给占位符(只要它也不是空/空白)。在某些 Windows™ 版本上,如果打印带有前导空格或空行的文本,也会发生这种情况。为了解决这个问题,请预处理数据并填充一些值到空数据中,例如空格(正如您已经尝试过的那样),以保留所有标记。

for /f "delims=" %a in (test.1) do set data=%a& set data=!data:,=","!& for /f "tokens=1-4 delims=," %i in ("!data!") do set a=%i-%j-%k-%l& echo !a:"=!

上面的代码对类似CSV格式的数据进行预处理,也适用于包含同一“单元格”内空格的数据。 例如,输出:key-value--windows 7 如果您的数据包含分隔符,并且希望将其保留为数据的一部分,则可以在for中更改分隔符或在预处理期间转义它。
更新(批量处理的实际应用): 使用此方法,您还可以自动填充(常见)数据,例如,如果要处理多个文件并且要从模板文件中读取文件名,则可以创建一个模板文件并从其中读取文件名,而不是为每个要处理的文件在命令提示符上键入文件名。
如果它们大多具有共同的扩展名,例如.txt,则只需像这样输入,,(空白数据),而不是每次键入.txt:
file1,,
file 2,,
file 3la,,
different file,.pdf

在您的代码中,空白处,,将预填充.txt(节省创建模板文件的时间)。

以下是传递给主处理代码之前对文件名进行预处理的代码:

for /f "delims=" %a in (test.1) do set data=%a& set data=!data:,=","!& for /f "tokens=1,2 delims=," %i in ("!data!") do (
REM replace empty cells with ".txt"
echo %j | find "." >nul && (set j=%j) || set j=.txt
set data=%i!j! & echo !data:"=!
)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接