批处理脚本输出到文本文件部分复制

Batch script output to text file partially duplicating

我的任务是查询一些主机名以获取它们存储在 BIOS 中的序列号。我用一个 for 循环处理文本文件中的主机名,用另一个 for 循环查询客户端的序列号,并将结果定向到另一个文本文件。

如果主机离线或没有响应,这没有问题。主机名被写入文本文件,序列号为空,然后脚本移动到输入文件中的下一个条目。但是,如果主机响应并且序列号存储在变量中,脚本最初会按原样写入输出文件,但随后它会写入另一行具有相同主机名和空白序列号的行,然后再移至文件中的下一行输入文件。

@ECHO OFF

set list=c:\temp\input.txt

for /F %%C in (%list%) do (
    for /F "skip=1" %%S in ('wmic /node:%%C bios get serialnumber') do ( 
        echo %%C - %%S >>c:\temp\output.txt)
    )

pause

这导致输出如下所示:

DC6068WA00829 -  
DC6054WA00178 -  
DC6061WA00065 - R93NSI3
DC6061WA00065 -  
DC6061WA00064 - R0KBN3S
DC6061WA00064 -  
DC6023LA034284 -  
DC6038LA034272 -  

如您所见,当主机因为离线或出于任何原因无法联系而没有响应时,它会按原样转到下一个。但是当一个人回应时,它会立即写下另一行,只有主机名和破折号。

我试过将写入命令作为单独的子例程调用发送到输出文件,我试过删除 %%S 变量的写入以查看它是否以某种方式产生干扰,我试过在将结果输出到文件之前将结果保存到不同的变量,但没有任何区别。

我可以毫无问题地清理生成的文件。我主要只是想知道我错过了什么会导致这种情况发生。

如有任何帮助或见解,我们将不胜感激。

你会注意到,当你 运行 自己时:

wmic /node:somehostname bios get serialnumber

它仍然有 Unicode cr/lf 个字符,您在 cmd 提示终端上看不到这些字符,因为它们显示为空行。然而,这会导致字符被分配给 %%C 元变量,并且 运行 再次循环这些字符,将显示文件中的两个条目。相反,我们检查变量是否存在并创建如果没有,这将确保我们只分配实际值。请注意,我们在这里使用 delayedexpansion,因为我们在 set 中使用代码块中的变量。

@echo off
setlocal enabledelayedexpansion
set "list=C:\temp\input.txt"

type nul>"C:\Temp\output.txt"
for /F %%C in (%list%) do (
    for /F "skip=1" %%S in ('wmic /node:%%C bios get serialnumber') do if not defined serial set "serial=%%C - %%S"
        echo(!serial!>>"C:\temp\output.txt"
)
type output.txt
pause

备注

我创建了 type nul>"C:\Temp\output.txt" 以确保我们不会追加到脚本的前 运行 中,如果您想要它追加,请删除该行。

  • wmic.exe 输出因不寻常的行结尾 cr/cr/lf
    而瘫痪 由于错误的 unicode 转换。
  • for /f 会跳过空行,但不能使用那些 cr/cr/lf 序列
    所以输出这些只有 %%C 的行。
  • 一个解决方案是另一个 for 解析大写字母 %%S%%s
  • 从技术上讲,所有 for /f 都是一行:

:: Q:\Test19\SO_55804785.cmd
@ECHO OFF
set "FileIn=c:\temp\input.txt"
set "FileOut=c:\temp\output.txt"

for /F "usebackq delims=" %%C in (
    "%FileIn%"
) do for /F "skip=1 delims=" %%S in (
    'wmic /node:%%C bios get serialnumber 2^>Nul ^|findstr "^." '
) do for /F "delims=" %%s in (
    "%%S"
) do echo %%C - %%s >>"%FileOut%"

pause