批量合并两个以制表符分隔的文本文件为一个文件

8
我可以帮助您翻译,内容与编程有关。您需要将两个文本文件合并为一个以制表符分隔的文本文件,并在批处理脚本中执行此操作。 例如: 文件1:
qwer
tyui
asdf

文件2:

1345
6876
8796

文件3:

qwer    1345
tyui    6876
asdf    8796

实际上,我所需要的只是一个类似于Unix命令的等价物:paste -d "\t" file1 file2 > file3


@Adam:Unix的paste命令将会生成他在file3中展示的结果。 - Carey Gregory
我需要结果准确地显示在file3中。 - user767990
3个回答

14
 @echo off

 set f1=1.txt
 set f2=2.txt
 set "sep=  "  % tab %

 (
   for /f "delims=" %%a in (%f1%) do (
      setlocal enabledelayedexpansion
       set /p line=
       echo(%%a!sep!!line!
      endlocal
   )
 )<%f2%

pause
goto :eof

1
哇!它运行得太好了!谢谢你,你是我的救星。现在我只是在尝试弄清楚它是如何工作的。这个 enabledelayedexpansion 本地变量是什么?还有 !sep! 和 !line! 是如何工作的? - user767990
2
+5 :-),绝对令人印象深刻,我不知道set /p可以从文件中读取多行内容,而且它似乎非常强大,因为它可以读取每个内容而无需使用延迟切换技术。很久以前我看到了一种全新的技术。 - jeb
1
@user767990 哎呀,这个有趣了... % tab % 是一个注释.. 没有制表符输出.. 只有一个双空格。setlocal enabledelayedexpansion ... endlocal 有点故事,但 setlocal 方面并不那么相关.. enabledelayedexpansion 方面实际上只是创建正常的行为.. !sep! 就像 %sep% 一样,但它可以正常工作。你可能会想知道为什么括号不匹配.. 如果你愿意,echo( 可以被替换为 echo/。 - barlop
@user767990 聪明的地方在于这种方法是可行的:C:>( set /p line= & set /p line= )<filename echo %line%,这样你就可以得到第二行,也就是说set命令在每次执行括号内的操作时都会读取文件的每一行。如果你只是简单地使用set /p line=<filename并且重复两次,那么你只会得到第一行。 - barlop
1
@barlop:不错,但是有误 :-) 查看 @echo off setlocal DisableDelayedExpansion for %%a in ("Hello!") DO echo %%a setlocal EnableDelayedExpansion for %%a in ("Hello!") DO echo %%a 与此的区别,你可以阅读 How the parser works - jeb
显示剩余10条评论

4

walid2me的答案非常棒,这只是一个小改动,展示了如何使它对像!^这样的字符在文件1.txt中变得安全,文件2.txt的内容是安全的,因为它使用set/p语法进行读取。

@echo off

 set f1=1.txt
 set f2=2.txt
 set "sep=  "  % tab %

 (
   setlocal DisableDelayedExpansion
   for /f "delims=" %%a in (%f1%) do (
      set "f1_line=%%a"
      setlocal EnableDelayedExpansion
       set /p f2_line=
       echo(!f1_line!!sep!!f2_line!
      endlocal
   )
   endlocal
 )<%f2%

pause
goto :eof

正如您所看到的,我只是将 %%a 的扩展移动到了 setlocal EnableDelayedExpansion 之前。
还有一个小缺陷,即 set/p 剥离尾部控制字符,例如单个CR,LF和TAB。这仅影响文件2.txt。
关于 set/p 的深入分析,请参见新技巧:set/p 可以从文件中读取多行

假设它是cmd /v:on,那么在for /f之前放置setlocal DisableDelayedExpansion,然后在set "f1_line=%%a"之后放置endlocal是否可以? - barlop
不,那么你每个循环都有一个endlocal,但没有进一步的setlocal,你将使用endlocal破坏f1_line变量。我编辑答案以确保安全,即使启用了DelayedExpansion。 - jeb

3

我不知道有哪个本地的Windows命令可以做到这一点,但是在这里提供了一组适用于Windows的Unix工具。


批处理脚本让我感到困惑 :) 你说得对,找不到内置工具来完成这项工作。 - user767990

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接