批处理:按列合并 txt 文件
我正在尝试将 txt 文件(其中第一列全部相等)合并到一个文件中。我在实验中获得了数千个。我使用 3 个输入文件作为示例来说明我想要实现的目标:
1.txt 2.txt 3.txt
l1 a1 l1 b1 l1 c1
l2 a2 l2 b2 l2 c2
l3 a3 l3 b3 l3 c3
因此所有输入文件都有共同的第一列。 我的愿望是获得以下输出:
out.txt
l1 a1 b1 c1
l2 a2 b2 c2
l3 a3 b3 c3
Attempt 1 of 3
:: hmm.bat=============================================
@echo off > hmm.txt & setLocal enableDELAYedeXpansion
echo AAAAAAAAAAaaaaaaaaaa............
pushd %*
for /f "tokens=1* delims= " %%a in (a1.txt) do (
>> hmm.txt echo. %%a hm
)
for %%j in (*.txt) do (
echo. %%j yes? >> hmm.txt
for /f "tokens=2* delims= " %%a in (%%j) do (
>> hmm.txt echo. %%a
)
)
popd
:: End_Of_Batch======================================
此批处理文件确实提取了我想要的列,但不是所有内容都在单独的列中,而是所有数据都在一个列中。我无法设法将输出放入单独的列中。
这次尝试(3 次中的 2 次)最终将给出我想要的:
::=============================================
@echo off > tral.txt & setLocal enableDELAYedeXpansion
set N=
for /f "tokens=1* delims= " %%a in (a1.txt) do (
set /a N+=1 & call :sub1 %%a & set A!N!=!C!
)
set N=
for /f "tokens=* delims= " %%a in (a1.txt) do (
set /a N+=1 & call :sub1 %%a & set B!N!=!C!
)
set N=
for /f "tokens=* delims= " %%a in (a2.txt) do (
set /a N+=1 & call :sub1 %%a & set C!N!=!C!
)
set N=
for /f "tokens=* delims= " %%a in (a3.txt) do (
set /a N+=1 & call :sub1 %%a & set D!N!=!C!
)
for /L %%a in (1 1 !N!) do (
>> tral.txt echo. !A%%a! !B%%a! !C%%a! !D%%a!
)
goto :eof
:sub1 set C to last token
:loop
if '%2' neq '' (
shift
goto :loop
)
set C=%1
goto :eof
::================================================
但是,要将其扩展到许多(数千个)文件,我需要重复该位
set N=
for /f "tokens=* delims= " %%a in (a*.txt) do (
set /a N+=1 & call :sub1 %%a & set x!N!=!C!
)
maaaaaaaany 次。我尝试使用循环来代替:
尝试 3 of 3
::=============================================
@echo off & setLocal enableDELAYedeXpansion
type nul > slow.txt
set N=
for /f "tokens=1* delims= " %%a in (a1.txt) do (
set /a N+=1 & call :sub1 %%a & set A!N!=!C!
)
for %%j in (*.txt) do (
set N=
for /f "tokens=* delims= " %%a in (%%j) do (
set /a N+=1 & call :sub1 %%a & set x!N!=!C!
)
)
for /L %%a in (1 1 !N!) do (
>> slow.txt echo. !A%%a! !x%%a!
)
goto :eof
:sub1 set C to last token
:loop
if '%2' neq '' (
shift
goto :loop
)
set C=%1
goto :eof
::=============================================
我最终得到第一列(所有数据文件都共有)和最后一个数据文件的第二列。 我不知道如何更新 !x%%a! 中的变量 x对于每个文件,将其打印在单独的列中。
或者,有谁知道是否可以在输出文件中所选行的末尾回显数据? 然后,我会将其回显到第一行的末尾,这将导致回显列中的所有数据。 使用
set /P line1=< hmm.txt
and then
echo.%line1% %%a>>hmm.txt
不会导致在第一行末尾出现回显,而是在最后一行末尾出现回显。
任何人都有解决方案吗?
I am trying to merge txt files (from which first column is equal in all) into one file. Thousands of them that I acquire in my experiments. I use 3 input files as an example to illustrate what I am trying to achieve:
1.txt 2.txt 3.txt
l1 a1 l1 b1 l1 c1
l2 a2 l2 b2 l2 c2
l3 a3 l3 b3 l3 c3
So all input files have the first column in common.
My wish is to get this output:
out.txt
l1 a1 b1 c1
l2 a2 b2 c2
l3 a3 b3 c3
Attempt 1 of 3
:: hmm.bat=============================================
@echo off > hmm.txt & setLocal enableDELAYedeXpansion
echo AAAAAAAAAAaaaaaaaaaa............
pushd %*
for /f "tokens=1* delims= " %%a in (a1.txt) do (
>> hmm.txt echo. %%a hm
)
for %%j in (*.txt) do (
echo. %%j yes? >> hmm.txt
for /f "tokens=2* delims= " %%a in (%%j) do (
>> hmm.txt echo. %%a
)
)
popd
:: End_Of_Batch======================================
This batch file does extract the columns I want, but rather than that everything is in separate columns, all data is in one single column. I have not been able to manage to get output into separate columns.
This attempt (2 of 3) would ultimately give what I want:
::=============================================
@echo off > tral.txt & setLocal enableDELAYedeXpansion
set N=
for /f "tokens=1* delims= " %%a in (a1.txt) do (
set /a N+=1 & call :sub1 %%a & set A!N!=!C!
)
set N=
for /f "tokens=* delims= " %%a in (a1.txt) do (
set /a N+=1 & call :sub1 %%a & set B!N!=!C!
)
set N=
for /f "tokens=* delims= " %%a in (a2.txt) do (
set /a N+=1 & call :sub1 %%a & set C!N!=!C!
)
set N=
for /f "tokens=* delims= " %%a in (a3.txt) do (
set /a N+=1 & call :sub1 %%a & set D!N!=!C!
)
for /L %%a in (1 1 !N!) do (
>> tral.txt echo. !A%%a! !B%%a! !C%%a! !D%%a!
)
goto :eof
:sub1 set C to last token
:loop
if '%2' neq '' (
shift
goto :loop
)
set C=%1
goto :eof
::================================================
However, to extend this to many (thousands) files, I would need to repeat the bit
set N=
for /f "tokens=* delims= " %%a in (a*.txt) do (
set /a N+=1 & call :sub1 %%a & set x!N!=!C!
)
maaaaaaaany times. I have tried using a loop instead:
Attempt 3 of 3
::=============================================
@echo off & setLocal enableDELAYedeXpansion
type nul > slow.txt
set N=
for /f "tokens=1* delims= " %%a in (a1.txt) do (
set /a N+=1 & call :sub1 %%a & set A!N!=!C!
)
for %%j in (*.txt) do (
set N=
for /f "tokens=* delims= " %%a in (%%j) do (
set /a N+=1 & call :sub1 %%a & set x!N!=!C!
)
)
for /L %%a in (1 1 !N!) do (
>> slow.txt echo. !A%%a! !x%%a!
)
goto :eof
:sub1 set C to last token
:loop
if '%2' neq '' (
shift
goto :loop
)
set C=%1
goto :eof
::=============================================
I end up with the first column (which all data files have in common), and the second column of the very last data file.
I do not know how to update the variable x in !x%%a! for each file, to get this printed in a separate column.
Alternatively, does anyone know if it is possible to echo data at the end of a chosen line in the output file?
I would then echo it to the end of the first line, which then would result in echoing all data in columns.
Using
set /P line1=< hmm.txt
and then
echo.%line1% %%a>>hmm.txt
does not result in echoing at the end of the first line, but rather at the end of the last line.
Anyone has a solution either way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
与此同时,我设法找到了解决方案(在 http://www.computing.net/answers/programming/merge-files-in-column-output/26553.html)。
也许有一天其他人也能很好地利用它。
首先它计算文件数(稍后使用文件数)。
不带扩展名的文件名列在文件“list.dat”中。
In the meantime I have managed to find the solution (with much help from others on http://www.computing.net/answers/programming/merge-files-in-column-output/26553.html).
Perhaps some day someone else has a nice use for this too.
First it counts the files (nr of files is used later on).
The files names without extension are listed in a file "list.dat".
我认为 BAT 编程不适合您想要完成的任务。您可能会发现一些复杂的解决方案,或者最终使用第三方工具来补充 BAT 编程(我立即想到了 SED),IMO 只会在方程式中添加另一个问题,要么强迫用户安装这样的工具,要么使您的程序复杂化BAT 的分发和安装具有相同的意图。
另一方面,使用任何通用编程语言进行编程来解决您的问题都是一项非常容易的任务。
所以,我会尝试 VB 或 javascript,它们几乎在所有 Windows 安装中都可用。看看这个并开始...
I don't think BAT programming is appropiate for what you want to acomplish. You might find some convoluted solution, or end up using a third party tool to complement BAT programming (SED comes immediately to my mind) would IMO only add another problem to the equation, either forcing the user to install such a tool, or complicating your BAT distribution and installation with the same intent.
On the other hand, solving your problem is a very easy task to program in any general purpouse programming language.
So, I would try either VB or javascript, which are available in almost all windows installations. Take a look at this and get started...
如果所有文件都具有相同的长度:
查找行数。
设置文件数量:
然后读取&合并每一行:
示例输出:
在 Win 10 CMD 上测试
If all files have same length:
To find number of lines.
Set number of files:
Then read & merge each line:
Sample output:
Tested on Win 10 CMD