[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[文本处理] [已解决]另外一个帖子,批处理如何在XML内查找内容,显示查找到的内容及后面8个字符?

本帖最后由 Bonnie 于 2022-11-14 16:09 编辑
  1. <# :
  2. cls&echo off&cd /d "%~dp0"&rem 编码ANSI
  3. set "tmpfile=%tmp%\t.t"
  4. powershell -NoProfile -ExecutionPolicy bypass "[IO.File]::ReadAllText(\"%~f0\",[Text.Encoding]::GetEncoding('GB2312'))|Invoke-Expression"
  5. for /f "tokens=1* delims=|" %%a in ('type "%tmpfile%"') do (
  6.     findstr /s /m "3101DF05" "%%a\*.xml"
  7. )
  8. pause
  9. exit
  10. #>
  11. $folder="C:\oud\traces";
  12. $subfolder=@("AC","ADS","AP");
  13. [System.Collections.ArrayList]$fdlist=@();
  14. for($i=0;$i -lt $subfolder.length;$i++){
  15.     $fd=$folder+'\'+$subfolder[$i];
  16.     if(test-path -literal $fd){
  17.         $folders=@(dir -literal $fd|?{$_ -is [System.IO.DirectoryInfo]});
  18.         for($j=0;$j -lt $folders.length;$j++){
  19.             [void]$fdlist.add($folders[$j]);
  20.         }
  21.     }
  22. }
  23. $tmpfile=$env:tmpfile;[System.Collections.ArrayList]$s=@();
  24. $newfolder=($env:USERPROFILE)+'\Desktop\'+(get-date).ToString('yyyyMMdd_HHmm')+'';
  25. if($fdlist.count -ge 1){
  26.     $arr=@($fdlist|sort {$_.CreationTime} -Descending);
  27.     write-host ('['+$arr[0].CreationTime.ToString('yyyy-MM-dd HH:mm:ss')+']'+$arr[0].FullName);
  28.     [void]$s.add($arr[0].FullName+'|'+$newfolder);
  29. }
  30. [void]$s.add('C:\AWRoot\dtwr\stcapi\home\temp|'+$newfolder);
  31. [IO.File]::WriteAllLines($tmpfile, $s, [Text.Encoding]::GetEncoding('GB2312'));
复制代码
这是上面这批处理运行后所显示的内容:   运行所显示出来的是查找3101DF05所在的文件名和路径。
[2022-11-13 10:40:20]C:\oud\traces\AP\637059140efe9889022951
C:\oud\traces\AP\637059140efe9889022951\637059140efe9889022951.TU.20221113-104020.xml
请按任意键继续. . .

我想达到的效果是运行后所显示的第二行文件名及路径这个文件里面的3101DF05及后面的8个字符。


大概说一下代码里面的内容:在C:\oud\traces目前下的AC、ADS、AP三个文件夹内寻找最新时间创建的文件夹。
    在最新时间创建的文件夹下查找XML文件里所包含的字符"3101DF05”。
(把C:\oud\traces下最新创建的乱码文件夹下的所有文件及C:\AWRoot\dtwr\stcapi\home\temp下所有的文件,复制到在当前桌面创建一个当前日期和时间的文件夹内。)
注:括号内的功能我不需要了。。另外一个程序需要用到。

可以给个文件做测试吗?

TOP

可以给个文件做测试吗?
BAT221110 发表于 2022-11-13 12:48



    链接: https://pan.baidu.com/s/1hSo3uTlgs7AOuRE05-RQtA?pwd=57er 提取码: 57er 复制这段内容后打开百度网盘手机App,操作更方便哦

TOP

不知道用FINDSTR如何达到这样的效果,我是用正则表达式实现的。

首先,把下面的文件存到OUD.VBS:
  1. FUNCTION READ4(FPATH)
  2. DIM ADOS
  3. SET ADOS = CREATEOBJECT("ADODB.STREAM")
  4. WITH ADOS
  5. .CHARSET = "UTF-8"
  6. .TYPE = 2
  7. .OPEN
  8. .LOADFROMFILE FPATH
  9. READ4 = .READTEXT
  10. .CLOSE
  11. END WITH
  12. SET ADOS = NOTHING
  13. END FUNCTION
  14. SUB MAIN4(SEARCH, FPATH)
  15. DIM REGEX, MATCH, MATCHES
  16. SET REGEX = NEW REGEXP
  17. REGEX.PATTERN = SEARCH & "........"
  18. SET MATCHES = REGEX.EXECUTE(READ4(FPATH))
  19. WSCRIPT.ECHO MATCHES(0)
  20. END SUB
  21. MAIN4 WSCRIPT.ARGUMENTS(0), WSCRIPT.ARGUMENTS(1)
复制代码
然后,把原来代码的第7行(findstr)换为:
  1.     findstr /s /m "3101DF05" "%%a\*.xml" > OUDTMP12421.TXT
  2.     SET /P DAT=<OUDTMP12421.TXT
  3.     CSCRIPT OUD.VBS //NOLOGO "3101DF05" %DAT%
复制代码
这三行的作用是把原先FINDSTR的输出存到一个临时文件,然后调用VBS。VBS中用正则表达式来提取你要的字符。

TOP

回复 4# BAT221110


    [2022-11-13 10:40:20]C:\oud\traces\AP\637059140efe9889022951
C:\Users\X230\Desktop\OUD.VBS(24, 1) Microsoft VBScript 运行时错误: 下标越界

C:\Users\X230\Desktop\OUD.VBS(24, 1) Microsoft VBScript 运行时错误: 下标越界

请按任意键继续. . .


运行提示错误。。下标越界

TOP

下载gawk( http://bcn.bathome.net/tool/4.1.0/gawk.exe )后,执行:
  1. gawk "/3101DF05.{8}/{print gensub(/^.*(3101DF05.{8}).*$/,\"\\1\",\"g\")}" 637059140efe9889022951.TU.20221113-104020.xml>out.txt
复制代码
结果(out.txt)
  1. 3101DF0531323334
复制代码

TOP

本帖最后由 BAT221110 于 2022-11-13 15:30 编辑

我用压缩包测试时可以的。可能是用单个文件测试通过,多个文件要稍微改动下。楼上用GAWK的方法更好。

TOP

本帖最后由 aloha20200628 于 2022-11-14 16:58 编辑

  1. @echo off
  2. set "inF=C:\oud\traces\AP\637059140efe9889022951\637059140efe9889022951.TU.20221113-104020.xml"
  3. set "p=3101df05" &setlocal enabledelayedexpansion
  4. for /f "delims=" %%a in ('findstr /i /r "%p%........" "%inF%" ') do (
  5. set "s=%%a" & set "s1=!s:*%p%=!"
  6. echo,%p%!s1:~,8!
  7. )
  8. endlocal &exit/b
复制代码

TOP

aloha20200628 发表于 2022-11-13 19:00



    这个方法厉害!

TOP

aloha20200628 发表于 2022-11-13 19:00


    方法是很好用。但是这个文件名不是固定的:
    C:\oud\traces\AP\637059140efe9889022951\637059140efe9889022951.TU.20221113-104020.xml
     有时候是在C:\oud\traces\AC\下。有时是在C:\oud\traces\ADS\下。
     程序会在这个目录下C:\oud\traces\自动生成文件夹。。要在AC或AP或ADS文件夹下寻找最新创建的文件夹。

TOP

你dir加个参数吧 最新时间出来了  直接FINDSTR

TOP

本帖最后由 aloha20200628 于 2022-11-14 16:59 编辑

备注》dir **中的 /o-d /tw 是按文件修改时间排序,/o-d /tc是按文件创建时间排序
  1. (dir/s/b/a-d/o-d/tw C:\oud\traces\*.xml)>tmp.txt&(set/p inF=<tmp.txt)&(del/q tmp.txt)
  2. set "p=3101df05" &setlocal enabledelayedexpansion
  3. for /f "delims=" %%a in ('findstr /i /r "%p%........" "%inF%" ') do (
  4. set "s=%%a" & set "s1=!s:*%p%=!"
  5. echo,%p%!s1:~,8!
  6. )
  7. endlocal &exit/b
复制代码

TOP

备注》dir **中的 /o-d /tw 是按文件修改时间排序,/o-d /tc是按文件创建时间排序
aloha20200628 发表于 2022-11-14 10:51



   
C:\Users\X230\Desktop>(dir/s/b/a-d/o-d/tw C:\oud\traces\*.xml ) 1>tmp.txt  & (set/p inF= 0<tmp.txt )  & (del/q tmp.txt )

C:\Users\X230\Desktop>set "p=3101DF05"   & setlocal enabledelayedexpansion

C:\Users\X230\Desktop>for /F "delims=" %a in ('findstr /r "3101DF05........" "C:\oud\traces\AP\637059140efe9889022951\637059140efe9889022951.TU.20221113-104020.xml" ') do (set "s=%a"   & set "s1=!s:*3101DF05=!"
echo,3101DF05!s1:~,8! )

C:\Users\X230\Desktop>endlocal   & pause & exit/b
请按任意键继续. . .

   大神,你好!好像  do动作没有运行。。。

TOP

刚下载了lz的样本文件,才知其中‘给CMD埋了个大坑’,目标字段‘3101DF05...’所在行的字符量=70680,远超过纯P单个变量的上限(8k),for (...) 和 set ... 根本扛不住findstr的返回值。如此本贴须请其他脚本代劳了。
再给一个cmd+cscript@js混编代码》
还是先用 dir /s/b/a-d/o-d/tw 获取指定目录下最新创建或修改的目标文件
  1. @set @v=1 /*
  2. @echo off
  3. (dir/s/b/a-d/o-d/tw C:\oud\traces\*.xml)>tmp.txt&(set/p inF=<tmp.txt)&(del/q tmp.txt)
  4. for /f "delims=" %%v in ('cscript /e:jscript "%~f0" "%inF%" ') do echo,%%v
  5. exit/b
  6. */
  7. var v = WSH.Arguments;
  8. var fso = new ActiveXObject('scripting.filesystemobject');
  9. var fp = fso.opentextfile(v(0));
  10. var alllines = fp.readall(); fp.Close();
  11. alllines = alllines.replace(/[\r\n]/g, '');
  12. var kwF = alllines.replace(/.*(3101DF05.{8}).*/gi, '$1');
  13. WSH.Echo(kwF);
复制代码

TOP

返回列表