我正在尝试将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
尝试1的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======================================
此批处理文件确实提取了我想要的列,但不是所有列都在单独的列中,所有数据都在一个列中。我无法设法将输出分成不同的列。
这种尝试(2/3)最终会给出我想要的东西:
::=============================================
@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的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!x %% a!对于每个文件,将其打印在单独的列中。
或者,是否有人知道是否可以在输出文件中选定行的末尾回显数据? 然后我会将它回显到第一行的末尾,然后这将导致回显列中的所有数据。 使用
set /P line1=< hmm.txt
然后
echo.%line1% %%a>>hmm.txt
不会导致在第一行的末尾回显,而是在最后一行的末尾回显。
任何人都有解决方案吗?
答案 0 :(得分:1)
与此同时,我设法找到了解决方案(在http://www.computing.net/answers/programming/merge-files-in-column-output/26553.html上得到了其他人的帮助。)
也许有一天,其他人对此也有很好的用处。
首先它计算文件(稍后使用文件的nr)。 没有扩展名的文件名列在文件“list.dat”中。
@echo off
SetLocal EnableDelayedExpansion
for /f %%a in ('dir/b *.txt') do (
set /a count+=1
set /a count1=count-1
)
echo total is !count!
echo !count1!
rem empty contents of files
type nul > x.txt
type nul > y.txt
type nul > z.txt
type nul > list.dat
setlocal
set first=y
(
for /f %%g in ('dir/b/a-d a*.txt') do (
if defined first (
set first=
set/p=%%~ng <nul
) else (
set/p=%%~ng <nul
)
)
)>>list.dat
for /f %%j in (list.dat) do (
echo. %%j
for %%a in (%%j) do find /n /v "" < %%a.txt >> x.txt
)
sort x.txt /o x.txt
set "regex=^\[[0-9]\]"
:loop
findstr /r "%regex%" x.txt >> y.txt
if not errorlevel 1 (
set "regex=^\[[0-9]%regex:~3%
goto loop
)
set cnt=
set line=
for /f "delims=" %%a in (y.txt) do (
set input=%%a
set input=!input:*]=!
set line=!line! !input!
if "!cnt!"=="!count1!" (
>> z.txt echo !line:~1!
set line=
)
set /a cnt=^(cnt + 1^) %% !count!
)
type nul > zz.dat
for /F "delims=" %%i in (z.txt) do (
set cnt=1
set rrow=
for %%j in (%%i) do (
set /A cnt-=1
if !cnt! equ 0 (set cnt=0 & set rrow=!rrow! %%j)
)
set cnt=2
set row=
for %%j in (%%i) do (
set /A cnt-=1
if !cnt! equ 0 (set cnt=2 & set row=!row! %%j)
)
set row=!row:~1!
echo. !rrow! !row!>> zz.dat
)
del x.txt
del y.txt
pause
答案 1 :(得分:1)
我认为BAT编程不适合您想要实现的目标。您可能会发现一些复杂的解决方案,或最终使用第三方工具来补充BAT编程(SED立即出现在我的脑海中)IMO只会在方程式中添加另一个问题,要么强制用户安装此类工具,要么使您的工作复杂化BAT的分配和安装具有相同的意图。
另一方面,使用任何通用purpouse编程语言编程是一项非常容易的任务。
所以,我会尝试VB或javascript,这几乎在所有Windows安装中都可用。看看这个并开始......
@set @junk=1 /*
@echo off
rem textcolumns text
cscript //nologo //E:jscript %0 %*
goto :eof
:allfiles
pushd %1
for /f %%a in ('dir /b /s *.txt') do
call :coltxt %%a
)
goto :eof
:coltxt
cscript //nologo //E:jscript %*
goto :eof
*/
function openFile(fn) {
var ForReading = 1, ForWriting = 2, ForAppending = 8;
var TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0;
var fso = new ActiveXObject("Scripting.FileSystemObject");
// Create the file, and obtain a file object for the file.
// fso.CreateTextFile(fn);
var f = fso.GetFile(fn);
// Open a text stream for input.
ts = f.OpenAsTextStream(ForReading, TristateUseDefault);
// Read from the text stream and display the results.
return ts;
}
function removeFirstWord(s) {
var p1=s.indexOf(" ");
if (p1>0) {
return s.substring(p1+1);
} else {
return new String();
}
}
function getCol(ts) {
var s;
s = ts.ReadLine();
s = removeFirstWord(s);
return s;
}
// main
x = WScript.Arguments;
fs = new Array(x.length);
for (var i=0; i<x.length; i++) {
fs[i] = openFile(x(i));
}
while (!fs[0].AtEndOfStream) {
var s = fs[0].ReadLine();
for (var i=1; i<fs.length; i++) {
s += getCol(fs[i]);
}
WScript.echo(s);
}
for (var i=0; i<fs.length; i++) {
fs[i].close();
}
答案 2 :(得分:0)
如果所有文件的长度相同:
for /f %i in ('find /c /v "" ^< 1.txt') do set n=%i
查找行数。
设置文件数:
set f=4
然后阅读并合并每一行:
for /l %b in (1,1,%n%) do (
set /p=l%b <nul
for /l %a in (1,1,%f%) do (
for /f "tokens=2" %i in ('find "l%b" ^< %a.txt') do (
set /p=%i <nul
))
echo:
)
样本输出:
l1 a1 b1 c1 d1
l2 a2 b2 c2 d2
l3 a3 b3 c3 d3
在Win 10 CMD上测试