Windows批处理:同时在多个文件行上迭代 [英] Windows batch: Iterate over mulitple files lines at the same time

查看:157
本文介绍了Windows批处理:同时在多个文件行上迭代的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以同时迭代多个文件的行?我需要通过加入两个不同文件中的行输出一个文件(并添加一些额外的字)。



我知道CMD命令:

  FOR%variable IN(set)DO command [command-parameters] 

但是,如果你需要在同一时间迭代两个文件,这没有帮助。
更精确地说,我需要如下:

 第一个文件未结束
line1< ; - 从第一个文件中读取一行
line2< - 从第二个文件读取一行
WRITE在第三个文件line1 + line2

我正在寻找一种方法来完成我之前在 dos批处理文件中描述的内容。谢谢!

解决方案

我知道3种基本技术,可以从中衍生出大量的杂交。



选项1 (此选项与wmz解决方案非常相似)



FOR / F并读取文件2,第二个FOR / F和SKIP选项。文件2必须在CALLed子程序中读取,以便在不中断文件1循环的情况下可以断开循环。



限制:




  • 空行会导致行脱离同步。

  • ; 开头的行将不会被读取,因为的默认EOL选项。如果需要,可以通过将EOL设置为新的行字符来解决。请参阅如何:FOR / F禁用EOF或使用引号作为分隔符

  • 行限制为最大长度为8191个字节。



此选项由于CALL

  @echo off 
setlocal disableDelayedExpansion
setfile1 = a.txt
setfile2 = b.txt
setout = out.txt

set / a cnt = 0
setskip =

& %out%(
for / fusebackq delims =%% A in(%file1%)do(
setfound =
call:readFile2
如果没有定义找到(echo %% A - )


类型%out%
exit / b

:readFile2
for / fusebackq%skip%delims =%% B in(%file2%)do(
set found = 1
echo %% A - %% B
goto:break

:break
set / a cnt + = 1
设置skip = skip =%cnt%
退出/ b




选项2



此选项通过使用FINDSTR在每行前面加上冒号后面的行号来解决空行问题。 FINDSTR用于只读取文件2中的第n行,因此不需要跳出第二个循环。



限制:




  • 前导冒号将从行中删除。

  • 行限制为最大长度为8191个字节。



此选项比选项1更慢



EDIT - 固定为仍输出行的代码if第二个档案已提早结束

  @echo off 
setlocal disableDelayedExpansion
setfile1 = a .txt
setfile2 = b.txt
setout = out.txt

>%file2%.tmpfindstr / n^ %file2%
>%out%(
for / ftokens = 1 * delims =:%% A in('findstr / n^%file1% ')do(
setfound =
for / ftokens = 1 * delims =:%% a in('findstr^ %% A:%file2%.tmp ')do(
set found = 1
echo %% B - %% b

如果未找到定义(echo %% B - )


del%file2%.tmp
type%out%


选项3



使用SET / P读取这两个文件。 FIND用于获取文件1中行数的计数,因为SET / P无法区分空白行和文件末尾之间的差异。



此选项消除



限制:




  • Lines必须使用< CR>< LF> 的Windows样式行终结符。 c>

  • 行限制为1021字节




此选项是目前为止最快的。

  @echo off 
setlocal enableDelayedExpansion
set file1 = a.txt
setfile2 = b.txt
setout = out.txt

for / f %% N in('type'% file1%<%file2%($ file1%)%out%file1%^ | find / c / v)do setcnt = %% N
> b $ b for / l %% N in(11%cnt%)do(
setln1 =
setln2 =
<& 9 set / p ln1 =
set / pln2 =
echo!ln1! - !ln2!


类型%out%


Is it possible to iterate over the lines of multiple files at the same time? I need to output a file by joining the lines in two different files (and add some extra words).

I know the CMD command:

FOR %variable IN (set) DO command [command-parameters]

But that does not help if you need to iterate over two files at the same time. More precisely, I need to the following:

While the first file is not ended
   line1 <- READ a line from the first file
   line2 <- READ a line from the second file
   WRITE on a third file line1 + line2

I'm looking for a way to accomplish what I'vve previously describing in a dos batch file. Thanks!

解决方案

I know of 3 basic techniques, from which a large number of hybrids could be derived.

Option 1 (this option is very similar to the wmz solution)

Read file 1 with a FOR /F and read file 2 with a second FOR /F with a SKIP option. File 2 must be read in a CALLed subroutine so that the loop can be broken without breaking the file 1 loop.

Limitations:

  • Blank lines will cause lines to get out of synch. Blank lines are included in the skip count but are not read by FOR /F.
  • Lines beginning with ; will not be read because of the default EOL option. This can be solved by setting EOL to a new line character if necessary. See HOW TO: FOR /F Disabling EOF or using a quote as delim
  • Lines are limited to a maximum length of 8191 bytes.

This option is slow because of the CALL and because the 2nd file must be read once for each line.

EDIT - code fixed to still output a line if 2nd file ends early

@echo off
setlocal disableDelayedExpansion
set "file1=a.txt"
set "file2=b.txt"
set "out=out.txt"

set /a cnt=0
set "skip="

>"%out%" (
  for /f "usebackq delims=" %%A in ("%file1%") do (
    set "found="
    call :readFile2
    if not defined found (echo %%A - )
  )
)
type "%out%"
exit /b

:readFile2
for /f "usebackq %skip% delims=" %%B in ("%file2%") do (
  set found=1
  echo %%A - %%B"
  goto :break
)
:break
set /a cnt+=1
set "skip=skip=%cnt%"
exit /b


Option 2

This option solves the blank line problem by using FINDSTR to prefix each line with the line number followed by a colon. FINDSTR is used to read only the nth line from file 2, so no need to break out of the 2nd loop.

Limitations:

  • Leading colons will be stripped from the lines. This limitation can be eliminated with extra code, but it will make it more complicated and slower.
  • Lines are limited to a maximum length of 8191 bytes.

This option is even slower than option 1

EDIT - code fixed to still output a line if 2nd file ends early

@echo off
setlocal disableDelayedExpansion
set "file1=a.txt"
set "file2=b.txt"
set "out=out.txt"

>"%file2%.tmp" findstr /n "^" "%file2%"
>"%out%" (
  for /f "tokens=1* delims=:" %%A in ('findstr /n "^" "%file1%"') do (
    set "found="
    for /f "tokens=1* delims=:" %%a in ('findstr "^%%A:" "%file2%.tmp"') do (
      set found=1
      echo %%B - %%b
    )
    if not defined found (echo %%B - )
  )
)
del "%file2%.tmp"
type "%out%"


Option 3

Use SET /P to read both files. FIND is used to get a count of the number of lines in file 1 because SET /P cannot tell the difference between a blank line and end of file.

This option eliminates a lot of limitations and complexity, but introduces its own limitations.

Limitations:

  • Lines must use Windows style line terminators of <CR><LF>. Unix style <LF> will not work.
  • lines are limited to 1021 bytes
  • trailing control characters are stripped from each line.

This option is by far the fastest. It is preferred as long as the limitations are acceptable.

@echo off
setlocal enableDelayedExpansion
set "file1=a.txt"
set "file2=b.txt"
set "out=out.txt"

for /f %%N in ('type "%file1%"^|find /c /v ""') do set "cnt=%%N"
>"%out%" 9<"%file1%" <"%file2%" (
  for /l %%N in (1 1 %cnt%) do (
    set "ln1="
    set "ln2="
    <&9 set /p "ln1="
    set /p "ln2="
    echo !ln1! - !ln2!
  )
)
type "%out%"

这篇关于Windows批处理:同时在多个文件行上迭代的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆