Board logo

标题: [文本处理] 批处理如何根据指定的列标题提取多个txt文本里的指定列 [打印本页]

作者: lwbu571    时间: 2011-11-20 11:28     标题: 批处理如何根据指定的列标题提取多个txt文本里的指定列

批处理怎样在多个txt中根据指定关键字获得列数据?
同一目录下多个txt,每个txt行数不同,列数不同;
每个txt第一行为列名,从第二行开始全为数字;
第一行列名中包含有GR,SP的列;他们所在列数各不相同;
我想将这两列数据读取出来形成新的txt,新txt文件名与旧文件名一致,请问该如何实现?
作者: CrLf    时间: 2011-11-20 12:19

适合处理少量大文件:
  1. @echo off&setlocal enabledelayedexpansion
  2. for %%a in (*新.txt) do (
  3.    set /p first=<%%a
  4.    set /a GR=SP=n=0
  5.    for %%b in (!first!) do (
  6.       set /a n+=1
  7.       for %%c in (GR SP) do if %%b==%%c set %%c=!n!&set "str=!str!        %%c "
  8.    )
  9.    if !GR! gtr !SP! set /a GR=SP,SP=!GR!
  10.    call :tokens "%%a"
  11.    )
  12. )
  13. pause&exit
  14. :tokens
  15. (for /f "useback tokens=%GR%,%SP%" %%a in (%1) do (
  16.    set str=
  17.    for %%c in (%%a %%b) do set "var=           %%c"&set str=!str!!var:~-11!
  18.    echo;!str!
  19. ))>#%%~na.txt
复制代码
适合处理大量小文件:
  1. @echo off&setlocal enabledelayedexpansion
  2. for %%a in (*新.txt) do (
  3.    set /p first=<%%a
  4.    for %%b in (!first!) do (
  5.       set /a n+=1
  6.       for %%c in (GR SP) do if %%b==%%c set %%c=!n!&set "str=!str!        %%c "
  7.    )
  8.    echo;!str!
  9.    for /f "useback eol=# delims=" %%b in ("%%a") do (
  10.       set str=&set n=
  11.       for %%c in (%%b) do (
  12.          set /a n+=1,"test=(n-SP)*(n-GR)"
  13.          if !test!==0 (
  14.             set "tmp=           %%c"
  15.             set "str=!str!!tmp:~-11!"
  16.          )
  17.       )
  18.       echo;!str!
  19.    )
  20. )>%%~na2.txt
  21. pause
复制代码

作者: yangfengoo    时间: 2011-11-20 13:02

  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "tokens=*" %%a in ('dir /b *.txt') do (
  3.     set/p txt1=<%%a
  4.     set /a n=0
  5. for %%b in (!txt1!) do (
  6.     set /a n+=1
  7. if %%b==GR set n1=!n!
  8.     if %%b==SP set n2=!n!
  9. )
  10. rem if !n1! gtr !n2! (set/a n1=!n2!,n2=!n1!)
  11. call :cc %%a !n1! !n2!
  12. )
  13. :cc
  14. (for /f "tokens=%2,%3" %%a in (%1) do echo %%a    %%b)>nul1
  15. del %1&ren nul1 %1
复制代码

作者: yangfengoo    时间: 2011-11-20 13:04

另提问以上代码中把
:cc
(for /f "tokens=%2,%3" %%a in (%1) do echo %%a    %%b)>nul1
del %1&ren nul1 %1
改为
:cc
(for /f "tokens=%2,%3" %%a in (%1) do echo %%a    %%b)>%1
为什么不行
作者: lwbu571    时间: 2011-11-20 13:31

谢谢各位,我可不可以再无耻的问句,我想把这些处理完后的txt批量导入excel应该怎么操作?
应为我需要每个文件第一列为GR,第二列为SP。
版主给的代码可不可以直接完成?省的我转excel了,呵呵,有点懒,有点贪,莫介意。。。
作者: CrLf    时间: 2011-11-20 14:00

怎不早说...没办法直接转 xls,不过可以转成 csv 格式:
  1. @echo off&setlocal enabledelayedexpansion
  2. for %%a in (*新.txt) do (
  3.    set /p first=<%%a
  4.    for %%b in (!first!) do (
  5.       set /a n+=1
  6.       for %%c in (GR SP) do if %%b==%%c set %%c=!n!
  7.    )
  8.    for /f "useback delims=" %%b in ("%%a") do (
  9.       set str=&set n=
  10.       for %%c in (%%b) do (
  11.          set /a n+=1,"1/(n-SP)/(n-GR)"||set str=!str!"%%c",
  12.       )
  13.       echo;!str!
  14.    )
  15. )>%%~na.csv 2>nul
  16. pause
复制代码

作者: CrLf    时间: 2011-11-20 14:38

回复 4# yangfengoo


    因为这里的 >%1 是发生在 for /f 读取 %1 文件内容之前的,所以当 for /f 试图读文件时 %1 已经是个空文件了
作者: lwbu571    时间: 2011-11-20 15:39

我晕,原txt真的成空文件了,新csv也啥也没有了。。。版主瞅瞅哦
不过也也学到了,txt中不可以对列排序?确定!
作者: yangfengoo    时间: 2011-11-20 15:44

你真的确定?
作者: powerbat    时间: 2011-11-21 08:53

楼主的文件好像是从数据库中导出的,为何不直接用数据库的操作方法呢?
作者: lwbu571    时间: 2011-11-21 10:31

仪器直接出的,我就是想整理后导入数据库的
作者: powerbat    时间: 2011-11-21 18:35

数据库的处理方式
  1. @set @n=0//&cscript.exe -e:jscript "%~f0"&exit /b
  2. folder = "C:\\Kate Green\\txt"; //txt文件所在目录
  3. flag = true;
  4. fso = new ActiveXObject("Scripting.FileSystemObject");
  5. tmpdir = fso.GetSpecialFolder(2)+"\\"+fso.GetTempName();
  6. fso.CreateFolder(tmpdir);
  7. //把文件转换成标准的csv文件,后面作为数据库处理
  8. fc = new Enumerator(fso.GetFolder(folder).files);
  9. for (; !fc.atEnd(); fc.moveNext()) {
  10.     var fi = fc.item();
  11.     if (fi.Path.slice(-4).toLowerCase()==".txt") {
  12.         var s = fi.OpenAsTextStream().ReadAll();
  13.         s = s.replace(/^\s+|\s*\n\s*/g,'\r\n').replace(/ +/g,',');
  14.         //让ADO把GR,SP这两列的数据类型识别成文本,以免ADO自动对数字进行优化去掉后面的零
  15.         if (flag) s = s.replace(/^.*\n/g,
  16.             function(s){return s+new Array(21).join(s.replace(/\bGR\b|\bSP\b/g,'#'));});
  17.         var ts = fso.OpenTextFile(tmpdir+'\\'+fi.Name, 2, true);
  18.         ts.write(s); ts.close();
  19.     }
  20. }
  21. //使用ADO处理文本数据
  22. strConnect = 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=' + tmpdir
  23.     + ';Extended Properties="text;HDR=yes;FMT=Delimited;";';
  24. AdoCnn = new ActiveXObject("ADODB.Connection");
  25. AdoCnn.ConnectionString = strConnect;
  26. AdoCnn.Open();
  27. AdoRsSchema = AdoCnn.OpenSchema(20);//adSchemaTables=20
  28. s = "GR,SP\r\n";
  29. AdoRs = new ActiveXObject("ADODB.Recordset");
  30. while (!AdoRsSchema.EOF) {
  31.     AdoRs.Open("SELECT [GR],[SP] FROM ["+AdoRsSchema("table_name")+"]", AdoCnn, 3);
  32.     if (flag) AdoRs.Move(20);
  33.     s += AdoRs.GetString(2, AdoRs.RecordCount, ",", "\r\n");
  34.     AdoRs.Close();
  35.     AdoRsSchema.MoveNext();
  36. }
  37. fso.OpenTextFile('result.csv', 2, true).write(s);
  38. fso.DeleteFolder(tmpdir);
复制代码

作者: powerbat    时间: 2011-11-21 19:24

if (flag) s = s.replace(/^.*\n/g,
            function(s){return s+new Array(21).join(s.replace(/\bGR\b|\bSP\b/g,'#'));});
哦,没必要作替换,直接function(s){return new Array(22).join(s);}
作者: lwbu571    时间: 2011-11-22 07:59

呵呵,又要慢慢消化了,先谢谢啦,我回去试试,有结果再来冒泡




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