从目录子树中的每个文本文件中提取第一行

时间:2017-06-04 12:45:11

标签: windows batch-file windows-10

我在树目录结构中设置了5000个CSV文件。 每个文件都是表示其enconding的第一行,然后是典型的CSV内容。

UTF-8
Key1,"Value 1",
Key2,"Value 2"
etc, etc...

如何快速收集每个文件的第一行以监督其编码集?

我在this answer的帮助下尝试了这一点,但我不清楚地理解批处理文件变量的所有语法细微差别,所以我得到的内容如Echo is on.

for /R D:\resources\ %%f in (*.csv) do (
    set /p line1=<%%f
    echo %line1% >> out.txt
)

如果部件单独执行(对于单个文件),它们可以正常工作。

我也在尝试单线

for /R D:\resources\ %f in (*.csv) do set /p line1=<%f & echo %line1% >> out.txt

但是这个将从第一个文件收集的值放入每个文件的输出中。

2 个答案:

答案 0 :(得分:2)

这里的主要问题是缺少delayed expansion,当您在同一代码块中编写读取变量时,需要这样做;没有它,你正在读取解析块时存在的变量值,所以之前执行它。这是固定代码:

@echo off
copy NUL out.txt
setlocal EnableDelayedExpansion
for /R "D:\resources" %%g in ("*.csv") do (
    set "line1="
    < "%%~g" set /P line1=""
    >> "out.txt" echo(!line1!
)
endlocal

此外,我引用了所有文件/目录路径,以避免出现空格或特殊字符的问题。我还撤消了redirection syntax,因为echo(!line1! >> "out.txt"也在>>前面输出 SPACE (后面的echo而不是 SPACE 看起来很奇怪,但当ECHO is {on|off}.中的读取行为空时,会阻止!line1!返回。

顺便说一下,您最初不需要准备空输出文件out.txt,只需使用for将整个>循环重定向到输出文件中,你把一对括号括起来:

@echo off
setlocal EnableDelayedExpansion
> "out.txt" (
    for /R "D:\resources" %%g in (*.csv) do (
        set "line1="
        < "%%~g" set /P line1=""
        echo(!line1!
    )
)
endlocal

要在命令提示符中直接执行相同操作,请尝试以下操作:

cmd /V /C (for /R "D:\resources" %g in ("*.csv") do @(set "line1=" ^& ^< "%~g" set /P line1="" ^& echo(!line1!)) ^> "out.txt"

答案 1 :(得分:0)

aschipfl's comment帮了忙。添加更正和完整的脚本以造福他人:

@echo off
copy NUL out.txt
SETLOCAL EnableDelayedExpansion
for /R D:\resources\ %%g in (*.csv) do (
  set /p line1=<%%g
  echo !line1! >> out.txt
)