Board logo

标题: [文本处理] 求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

  1. # 保存了ANSI编码
  2. /Code="([^"]+)"/ {A = gensub(/^.*Code="([^"]+)".*$/, "\\1", "g", $0)}
  3. /Name="([^"]+)"/ {B = gensub(/^.*Name="([^"]+)".*$/, "\\1", "g", $0)}
  4. /Tender="([^"]+)"/ {C = gensub(/^.*Tender="([^"]+)".*$/, "\\1", "g", $0)}
  5. END {print FILENAME "+" A "+" B "+" C}
复制代码
以ANSI编码格式保存为test.awk
  1. @echo off
  2. @rem 保存为ANSI格式
  3. set "_gawk.exe=1"
  4. set "_test.awk=1"
  5. set "_test.bat=1"
  6. set "_test.txt=1"
  7. (for /f "tokens=*" %%a in ('dir/s/b/a-d') do (
  8. if not defined _%%~nxa gawk -f.\test.awk "%%~fa"
  9. ))>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

  1. @echo off
  2. for /f "delims=" %%a in ('dir /s /b /a-d^|findstr /v %~nx0') do (
  3.     setlocal enabledelayedexpansion
  4.     for /f "delims=" %%b in ('findstr "Code Name Tender" "%%a"') do (
  5.         for %%i in (%%b) do (
  6.             if "!str!"=="Code" (
  7.                 set Code=%%~i
  8.             ) else if "!str!"=="Name" (
  9.                 set Name=%%~i
  10.             ) else if "!str!"=="Tender" (
  11.                 set Tender=%%~i
  12.             )
  13.             set str=%%~i
  14.         )
  15.     )
  16.     if defined Code echo,%%a !Code! !Name! !Tender!
  17.     endlocal
  18. )
  19. pause
复制代码

作者: qixiaobin0715    时间: 2023-1-19 11:11

楼上代码可以简化一下:
  1. @echo off
  2. set /a _Code=_Name=_Tender=1
  3. for /f "delims=" %%a in ('dir /s /b /a-d^|findstr /v %~nx0') do (
  4.     setlocal enabledelayedexpansion
  5.     for /f "delims=" %%b in ('findstr "Code Name Tender" "%%a"') do (
  6.         for %%i in (%%b) do (
  7.             if defined _!str! set !str!=%%~i
  8.             set str=%%~i
  9.         )
  10.     )
  11.     if defined Code echo,%%a !Code! !Name! !Tender!
  12.     endlocal
  13. )
  14. 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 你自行修改代码第二行
  1. @if(0)==(0) echo off
  2. set "folder=text"
  3. dir "%folder%\*.*" /b /a-d /s |cscript.exe //NoLogo //E:JScript "%~f0"
  4. pause&exit
  5. @end
  6. function SaveText(filename, text, charset) {
  7.   var stream;
  8.   stream = new ActiveXObject("ADODB.Stream");
  9.   stream.type = 2;
  10.   stream.charset = charset;
  11.   stream.open();
  12.   stream.writeText(text);
  13.   stream.saveToFile(filename, 2);
  14.   stream.close();
  15. }
  16. var fso = new ActiveXObject('Scripting.FileSystemObject'),
  17. re = /(Code="|Name="|Tender=")([^"]+)"/img,
  18. result = ''
  19. while (!WSH.StdIn.AtEndOfStream){
  20.        var file = WSH.StdIn.ReadLine(),
  21.        f = fso.OpenTextFile(file,1),
  22.        content = f.ReadAll();
  23.        f.Close();
  24.        content.replace(re, function($a,$b,$c)
  25.        {
  26.            file += $c != null ? ( ' ' + $c ):'';
  27.        })
  28.        result += result != '' ? '\n' + file : file
  29. }
  30. SaveText("result.txt",result,"utf-8")
  31. WSH.Echo(result)
复制代码
  1. @echo off
  2. set "folder=text"
  3. 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 "
  4. 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
  1. @if(0)==(0) echo off
  2. set "folder=text"
  3. dir "%folder%\*.*" /b /a-d /s |cscript.exe //NoLogo //E:JScript "%~0"
  4. pause&exit
  5. @end
  6. function SaveText(filename, text, charset) {
  7.        var stream;
  8.        stream = new ActiveXObject("ADODB.Stream");
  9.        stream.type = 2;
  10.        stream.charset = charset;
  11.        stream.open();
  12.        stream.LoadFromFile(filename)
  13.        stream.Position = stream.Size
  14.        stream.writeText(text);
  15.        stream.saveToFile(filename, 2);
  16.        stream.close();
  17. }
  18. var fso = new ActiveXObject('Scripting.FileSystemObject'),
  19. re = /(Code="|Name="|Tender=")([^"]+)"/img,
  20. result = '';
  21. fso.CreateTextFile("result.txt", true);
  22. while (!WSH.StdIn.AtEndOfStream){
  23.        var file = WSH.StdIn.ReadLine(),
  24.        f = fso.OpenTextFile(file,1),
  25.        content = f.ReadAll();
  26.        f.Close();
  27.        content.replace(re, function($a,$b,$c)
  28.        {
  29.            file += $c != null ? ( ' ' + $c):'';
  30.        })
  31.        WSH.Echo(file)
  32.        SaveText("result.txt",file +'\n',"utf-8")
  33. }
复制代码





欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2