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

时间:2019-04-23 05:21:35

标签: batch-file command-prompt

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

如果主机处于脱机状态或没有响应,则此方法没有问题。主机名被写入文本文件,序列号为空,然后脚本移至输入文件中的下一个条目。但是,如果主机响应并且序列号存储在变量中,则脚本最初会按原样写入输出文件,但是随后它将写入具有相同主机名和空序列号的另一行,然后再移至输入文件。

import * as util from './util';  // <= import module into itself

export const func1 = () => {
  return 'hello ' + util.func2();  // <= use the module
}

export const func2 = () => 'world';

这将导致输出如下所示:

import * as sinon from 'sinon';
import * as util from './util';

describe('func1', () => {
  it('should work', () => {
    const stub = sinon.stub(util, 'func2').returns('everyone');
    expect(util.func1()).toBe('hello everyone');  // Success!
  });
});

如您所见,当主机由于脱机或由于某种原因而无法联系而无法响应时,它将按原样移动到下一个主机。但是当一个人响应时,它立即写出另一行,其中只包含主机名和破折号。

我尝试将写命令作为单独的子例程调用输出到输出文件,我尝试删除%% S变量的写操作以查看是否在某种程度上造成干扰,我尝试保存将结果输出到不同的变量,然后再将其输出到文件,但没有任何区别。

我可以清理生成的文件而没有太多问题。我主要只是想知道我所缺少的会导致这种情况发生的原因。

任何帮助或见识将不胜感激。

2 个答案:

答案 0 :(得分:2)

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

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",以确保我们不会追加到脚本的先前运行中,如果要追加,请删除该行。

答案 1 :(得分:0)

  • wmic.exe的输出以cr/cr/lf结尾的异常行残废,
    错误的unicode转换导致的结果。
  • for /f将跳过空行,但不能使用那些cr/cr/lf序列
    因此,仅输出%%C的这些行。
  • 一种解决方案是另一种for%%S解析大写%%s
  • 从技术上讲,所有for /f都是一行:

:: Q:\Test\2019\04\23\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