我有一个包含一些txt.files的文件夹,例如
FILE1.TXT:
'NumberOfEntries'|'TotalAmount1'|'TotalAmount2'
'10'|'150250.02'|'327535.49'
FILE2.TXT:
'NumberOfEntries'|'TotalAmount1'|'TotalAmount2'
'15'|'327551.09'|'18761432.56'
File3.txt:
'NumberOfEntries'|'TotalAmount1'|'TotalAmount2'
'20'|'100000.44'|'220030.90'
依旧......
我需要的是总结它,保持标题并将第二行的值相加,得到这样的结果:
FileALL.txt:
'NumberOfEntries'|'TotalAmount1'|'TotalAmount2'
'45'|'577801.55'|'19308998.95'
我需要这是通用的,对于其他类型的标题,对于具有更多或更少列的文件等都是必需的。
到目前为止,我设法从第一个文件中获取标题,但其余的我有点卡住了:
del "%CD%\%year%\ALL\fileALL.txt"
for /f "tokens=* delims=" %%a in (%year%\folder\file_01.txt) do (
echo %%a >> "%CD%\%year%\ALL\fileALL.txt"
goto _ExitForLoop
)
:_ExitForLoop
for %%F in (%year%\folder\*.txt) do (
set /a total1=0
set /a total2=0
set /a total3=0
for /f "usebackq tokens=1 delims=|" %%a in ("%%F") do set /a total1+=%%a
for /f "usebackq tokens=2 delims=|" %%b in ("%%F") do set /a total2+=%%b
for /f "usebackq tokens=3 delims=|" %%c in ("%%F") do set /a total3+=%%c
echo %total1%|%total2%|%total3% > "%CD%\%year%\ALL\fileALL.txt"
)
exit /b
答案 0 :(得分:3)
@echo off
setlocal EnableDelayedExpansion
rem Read the header and get the number of columns from it
for %%F in (*.txt) do set /P "header=" < %%F & goto ExitForLoop
:ExitForLoop
set "cols=0"
set "line=%header%"
:nextCol
for /F "tokens=1* delims=|" %%a in ("%line%") do (
set /A cols+=1
set "line=%%b"
)
if defined line goto nextCol
rem Initialize the array of totals
for /L %%i in (1,1,%cols%) do set "total[%%i]=0"
for %%F in (*.txt) do (
for /F "usebackq skip=1 delims=" %%L in ("%%F") do (
set "line=%%L"
for /L %%i in (1,1,%cols%) do (
for /F "tokens=1* delims=|" %%a in ("!line!") do (
set "col=%%a"
set "col=!col:'=!"
set /A "total[%%i]+=!col:.=!"
set "line=%%b"
)
)
)
)
rem Show totals
< NUL (
echo !header!
for /L %%i in (1,1,%cols%) do (
if %%i equ 1 (
set /P "='!total[%%i]!'"
) else (
set /P "=|'!total[%%i]:~0,-2!.!total[%%i]:~-2!'"
)
)
echo/
) > fileALL.txt
输出:
'NumberOfEntries'|'TotalAmount1'|'TotalAmount2'
'45'|'577801.55'|'19308998.95'
备注:强>
答案 1 :(得分:1)
Batch没有本机浮点支持,并且可靠地解析文本通常很不方便。
您可以使用我的JREPL.BAT regular expression find/replace utility通过一些用户提供的JScript有效地解决此问题。 JREPL.BAT是纯脚本(混合JScript /批处理),可以在XP之后的任何Windows机器上本机运行。
以下解决方案使用问题中列出的确切格式。它假定所有行都具有正确的列数,并且每个字段都有一个值。它还假定每个文件的最后一行由\r\n
或\n
终止。
代码很长。我使用^
行继续来使代码更容易阅读。
type "%year%\folder\*.txt" 2>nul|jrepl ^
"^'(\d+)'\|'(\d*\.?\d*)'\|'(\d*\.?\d*)'$ ^.+"^
"a+=parseInt($2);b+=parseFloat($3);c+=parseFloat($4);false h=$0;false"^
/jbeg "var h,a=0,b=0,c=0; function r(n){return Math.round(n*100)/100}"^
/jend "output.WriteLine(''+h+'\r\n\''+a+'\'|\''+r(b)+'\'|\''+r(c)+'\'')"^
/t " " /jmatch /o "%year%\ALL\fileALL.txt"
type
命令将每个文件合并为一个数据流,这就是每个文件必须以\n
结尾的原因。输出通过管道传输到JREPL,完成剩下的工作。
/jmatch
选项将替换字符串视为已计算的JScript表达式,并仅输出匹配的替换值。
/t " "
选项将搜索和替换字符串视为一组空格分隔的字符串。第一个搜索字符串由第一个替换字符串替换,第二个搜索字符串由第二个替换字符串替换,等等。
/o
选项指定输出文件。
/jbeg
选项定义并初始化变量以保存标头记录以及三个聚合列值。它还定义了一个将浮点数舍入到两个小数位的函数。需要舍入,因为浮点数不能准确表示数字。
第一个搜索字符串(捕获为$1
)与数据行匹配,并捕获$2
,$3
和$4
中的每个字段值。相应的替换JScript字符串解析值并将它们添加到聚合值。它返回false
以禁用任何正常输出。
第二个搜索字符串(捕获为$5
)匹配第一个未匹配的整行。如果文件格式正确,那么这将始终是标题记录。替换JScript字符串只是将匹配的字符串($0
始终表示整个匹配的字符串)存储在标头变量中,并返回false
以禁用输出。最后一个标题找到了“胜利”,但我认为它们都是一样的。
最后,/jend
选项是终结代码,用于写出标题行和最终聚合值行,并进行适当的舍入。