我对 Windows 中的“for”批处理命令有疑问。
我有一个名为keys.txt的文件,其中包含这一行..
键,值,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修改为
键、值、、windows7
第三个变量打印为windows7。我希望第三个变量为空,第四个变量为 windows7。如果我在两个逗号之间留一个空格,就像这样
键,值,,windows7
然后它将第三个变量打印为空,将第四个变量打印为Windows7。
有人知道我如何使之前的情况(即没有空格的情况)也能正常工作吗?
试试这个。想法来自这里
该脚本预处理每一行,将文本 #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
for
旨在在某些系统上不保留 null/空标记,因此将下一个标记分配给占位符(只要它也不为 null/空)。在某些版本的 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:"=!
)
为了使其与制表符分隔的值一起使用,我做了以下操作,作为对贝利撒留博士答案的修改:
@echo off
setlocal enabledelayedexpansion
for /f "tokens=*" %%X in (keys.txt) do (
set "work=%%X"
for /l %%i in (1,1,3) do set "work=!work: = #NUL# !"
for /F "tokens=1,2,3,4*" %%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 -------------
))
pause >nul