标题: [文本处理] 求BAT代码批量取文件里的字段值保存到txt [打印本页]
作者: 304802301 时间: 2023-1-18 19:06 标题: 求BAT代码批量取文件里的字段值保存到txt
大佬们新年好!求一个bat
源文件下面有多个文件夹,每个文件里面有多个文件(可能有多层路径的情况),每个文件格式不一定,但都可以用记事本方式打开。
我的目的是要取每个文件里面的几个字段的值,取出来后保存到一个txt文件中。
字段是这样的,Code="X" Name="XX" Tender="XXX",我要取的就是Code=""、Name=""、Tender="",三个字段,每个字段两个引号里面的值。但这几个字段不一定每个文件都会有,字段的顺序前后不一定,出现在文件的哪个位置也不一定。
保存到txt里有这样的要求:文件完整路径+文件名+Code值+Name值+Tender值,每个文件取出来的数据放一行,下一个文件的数据放下一行,以此类推。
示例文件放在了网盘:链接:https://pan.baidu.com/s/10AZXPUdMyn3EO6H9wjspNw 提取码:2alj
感谢大佬!
作者: hfxiang 时间: 2023-1-18 21:28
将- # 保存了ANSI编码
- /Code="([^"]+)"/ {A = gensub(/^.*Code="([^"]+)".*$/, "\\1", "g", $0)}
- /Name="([^"]+)"/ {B = gensub(/^.*Name="([^"]+)".*$/, "\\1", "g", $0)}
- /Tender="([^"]+)"/ {C = gensub(/^.*Tender="([^"]+)".*$/, "\\1", "g", $0)}
- END {print FILENAME "+" A "+" B "+" C}
复制代码
以ANSI编码格式保存为test.awk
将- @echo off
- @rem 保存为ANSI格式
- set "_gawk.exe=1"
- set "_test.awk=1"
- set "_test.bat=1"
- set "_test.txt=1"
- (for /f "tokens=*" %%a in ('dir/s/b/a-d') do (
- if not defined _%%~nxa gawk -f.\test.awk "%%~fa"
- ))>test.txt
复制代码
以ANSI编码格式保存为test.bat
下载gawk( http://bcn.bathome.net/tool/4.1.0/gawk.exe )后,将gawk.exe、test.awk及test.bat放置到"D:\实例"文件夹中,双击test.bat后得到的test.txt即为你需要的结果
作者: 304802301 时间: 2023-1-18 21:44
回复 2# hfxiang
大佬,感谢回复!但好像双击bat后一闪而过,没有txt产生
作者: hfxiang 时间: 2023-1-19 10:42
回复 3# 304802301
请确保
1、test.awk 及 test.bat以已 ANSI 编码格式保存
2、gawk.exe、test.awk 及 test.bat 已放置到 "D:\ 实例" 文件夹中
作者: qixiaobin0715 时间: 2023-1-19 10:45
- @echo off
- for /f "delims=" %%a in ('dir /s /b /a-d^|findstr /v %~nx0') do (
- setlocal enabledelayedexpansion
- for /f "delims=" %%b in ('findstr "Code Name Tender" "%%a"') do (
- for %%i in (%%b) do (
- if "!str!"=="Code" (
- set Code=%%~i
- ) else if "!str!"=="Name" (
- set Name=%%~i
- ) else if "!str!"=="Tender" (
- set Tender=%%~i
- )
- set str=%%~i
- )
- )
- if defined Code echo,%%a !Code! !Name! !Tender!
- endlocal
- )
- pause
复制代码
作者: qixiaobin0715 时间: 2023-1-19 11:11
楼上代码可以简化一下:- @echo off
- set /a _Code=_Name=_Tender=1
- for /f "delims=" %%a in ('dir /s /b /a-d^|findstr /v %~nx0') do (
- setlocal enabledelayedexpansion
- for /f "delims=" %%b in ('findstr "Code Name Tender" "%%a"') do (
- for %%i in (%%b) do (
- if defined _!str! set !str!=%%~i
- set str=%%~i
- )
- )
- if defined Code echo,%%a !Code! !Name! !Tender!
- endlocal
- )
- pause
复制代码
作者: 304802301 时间: 2023-2-18 12:27
本帖最后由 304802301 于 2023-2-18 16:31 编辑
回复 6# qixiaobin0715
大佬,文件少的时候很快,但有1000W个文件的时候,24小时了,cmd界面还是黑屏状态,都不知道有没有在正常运行。下面两点能不能麻烦修改下。。。感谢
1、在cmd窗口中展示已经取到了第几个文件,当前文件的这些值也展示出来
2、获取第一个文件的时候,就把这个文件的这些值马上记录到指定路径的txt里,然后获取第二个文件,然后也立马把第二个文件的信息追加到 txt里,以此类推。这样可以按需分批处理
作者: terse 时间: 2023-2-18 21:58
本帖最后由 terse 于 2023-2-19 20:14 编辑
先测试效率能否提高,其他要求再说
PS:修改了输出文件编码为UTF-8 文件名result.txt
另外 测试文件夹名为text 你自行修改代码第二行- @if(0)==(0) echo off
- set "folder=text"
- dir "%folder%\*.*" /b /a-d /s |cscript.exe //NoLogo //E:JScript "%~f0"
- pause&exit
- @end
-
- function SaveText(filename, text, charset) {
- var stream;
- stream = new ActiveXObject("ADODB.Stream");
- stream.type = 2;
- stream.charset = charset;
- stream.open();
- stream.writeText(text);
- stream.saveToFile(filename, 2);
- stream.close();
- }
-
- var fso = new ActiveXObject('Scripting.FileSystemObject'),
- re = /(Code="|Name="|Tender=")([^"]+)"/img,
- result = ''
-
- while (!WSH.StdIn.AtEndOfStream){
- var file = WSH.StdIn.ReadLine(),
- f = fso.OpenTextFile(file,1),
- content = f.ReadAll();
- f.Close();
- content.replace(re, function($a,$b,$c)
- {
- file += $c != null ? ( ' ' + $c ):'';
- })
- result += result != '' ? '\n' + file : file
-
- }
- SaveText("result.txt",result,"utf-8")
- WSH.Echo(result)
复制代码
- @echo off
- set "folder=text"
- powershell "[regex]$re = '(?smi)(?<=Name=\"^|Code=\"|Tender=\")([^^\"]*)';(dir %folder% -File -Recurse).FullName.ForEach({$_+ ' '+($re.Matches((gc $_ -Raw)).Value -join ' ')}) | Out-File result.txt -Encoding utf8 "
- pause
复制代码
作者: 304802301 时间: 2023-2-19 00:02
回复 8# terse
哥,第一段提示:系统找不到指定的文件。第二段正在验证
作者: terse 时间: 2023-2-19 10:59
回复 9# 304802301
检查一下 bat文件和文本文件编码呢
作者: 304802301 时间: 2023-2-19 17:58
回复 10# qixiaobin0715
增加临时文件确实会提高效率,,执行的时候temp文件在一直增加,但最终的result.txt里面只记录了H:\1\%i !Code! !Name! !Tender!
作者: 304802301 时间: 2023-2-19 18:17
回复 11# terse
第一段可以运行了,需要填入自定义路径。我看了实际效果是读取一个文件后信息就记录到txt里。但有个2小问题,1是其他字段的值也记录了,我只需要三个字段的值就行了。2是能不能定义下记录到txt的编码为utf-8的。现在的txt里有2种编码
作者: terse 时间: 2023-2-19 20:07
回复 13# 304802301
不清楚你的环境,我这边测试了你的样本,正常获取到三个字段关键词 输出编码问题 JS修改了一下 再试一下呢
作者: 304802301 时间: 2023-2-19 22:16
回复 14# terse
大佬,使用你修改后的第一段代码后,不是读取一个写入一个了,cmd界面持续2个小时了还没有txt输出。。。
作者: 304802301 时间: 2023-2-20 10:34
回复 6# qixiaobin0715
你好,昨天那个含有temp临时文件的代码能再发一下不?我的想法是:因为临时文件中包含所有的文件的所有内容,所以temp文件不要删,我可以依据这个temp文件删除其他内容,来保留我想要的内容。
作者: qixiaobin0715 时间: 2023-2-20 10:42
本帖最后由 qixiaobin0715 于 2023-2-20 10:44 编辑
回复 15# 304802301
删除的原因是:
1.批处理不适合多种编码的文件混合处理;
2.最好是文件最后一行有回车键;
3.给出的代码未考虑周全,有问题;
4.楼主提供的文件是杜撰的,最好提供真实文件,以免测试没问题,实际运行可能会出问题;
5.原来的代码也没有保存。
作者: terse 时间: 2023-2-20 11:31
回复 14# 304802301 - @if(0)==(0) echo off
- set "folder=text"
- dir "%folder%\*.*" /b /a-d /s |cscript.exe //NoLogo //E:JScript "%~0"
- pause&exit
- @end
-
- function SaveText(filename, text, charset) {
- var stream;
- stream = new ActiveXObject("ADODB.Stream");
- stream.type = 2;
- stream.charset = charset;
- stream.open();
- stream.LoadFromFile(filename)
- stream.Position = stream.Size
- stream.writeText(text);
- stream.saveToFile(filename, 2);
- stream.close();
- }
-
- var fso = new ActiveXObject('Scripting.FileSystemObject'),
- re = /(Code="|Name="|Tender=")([^"]+)"/img,
- result = '';
- fso.CreateTextFile("result.txt", true);
- while (!WSH.StdIn.AtEndOfStream){
- var file = WSH.StdIn.ReadLine(),
- f = fso.OpenTextFile(file,1),
- content = f.ReadAll();
- f.Close();
- content.replace(re, function($a,$b,$c)
- {
- file += $c != null ? ( ' ' + $c):'';
- })
- WSH.Echo(file)
- SaveText("result.txt",file +'\n',"utf-8")
- }
复制代码
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |