Board logo

标题: [文本处理] 【已解决】批处理如何在每行文字中,提取重复内容? [打印本页]

作者: 每天几分    时间: 2022-9-30 19:36     标题: 【已解决】批处理如何在每行文字中,提取重复内容?

本帖最后由 每天几分 于 2022-10-3 16:21 编辑

有一个txt文本,每行大概5-30字,N行。
能否把每行文字中,与后面重复出现的文字提取出来到一个新的txt中呢?谢谢!
单字不提取,只提取5个字的重复。

例如:
人生本就充满了矛盾
任何人都无可奈何
仿佛地狱中的火焰
常与寂寞为伍
拿他都无可奈何
跟他充满了矛盾
不得不与寂寞为伍
这段旅途实在太长
……

提取:
充满了矛盾
都无可奈何
与寂寞为伍
……
作者: yhcfsr    时间: 2022-9-30 23:16

POWERSHELL
  1. $len_str = 5          #重复字符串长度
  2. $file = '.\0.txt'     #文件
  3. #====================================
  4. $dic = @{}
  5. $ErrorActionPreference = 'SilentlyContinue';
  6. gc |%{
  7.     $len = $_.Length;
  8.     if($len -lt $len_str){continue;}
  9.     for($i = 0;$i -lt $len-$len_str+1;$i++){
  10.         $key = $_.Substring($i,$len_str)
  11.        $dic.Add( $key,0)
  12.        if($? -eq $false){$dic[$key] +=1}      
  13.     }
  14. }
  15. foreach($key in $dic.Keys){
  16.     $cnt = $dic.Item($key)
  17.     if($cnt){$key+":重复$cnt 次"}
  18. }
复制代码

作者: 每天几分    时间: 2022-9-30 23:51

回复 2# yhcfsr


    你好,我不太会ps,只懂一点bat。我运行后 出现如下
  1. 位于命令管道位置 1 的 cmdlet Get-Content
  2. 请为以下参数提供值:
  3. Path[0]:
复制代码

作者: WHY    时间: 2022-10-2 17:24

  1. @if(0)==(0) echo off
  2. type 1.txt | cscript //nologo //e:jscript "%~f0" > new.txt
  3. pause & exit /b
  4. @end
  5. var len = 5, map = {};
  6. while( !WSH.StdIn.AtEndOfStream ){
  7.     var str = WSH.StdIn.ReadLine();
  8.     for( var i = 0; i < str.length - len + 1; i++ ){
  9.         var key = str.substr(i, len);
  10.         map[key] = map.hasOwnProperty(key) ? map[key] + 1 : 1;
  11.     }
  12. }
  13. for( key in map ) if( map[key] > 1 ) WSH.Echo(key);
复制代码

作者: aloha20200628    时间: 2022-10-4 17:30

给一段纯P代码,本想用js再优化一步其中的字符串长度计算代码,但实测结果,后者比前者竟然慢了...
纯P代码中的字符串长度计算算法源引自一个被认为P史以来非常经典的案例(参见 http://www.bathome.net/thread-4482-1-1.html

以下代码均假设源文本文件与代码脚本在同一目录
一。纯P方案
  1. @echo off
  2. set srcF="a.txt" &set newF="a.new"
  3. set/a "m=0","fsL=5" &::设置重复字段长度
  4. setlocal enabledelayedexpansion
  5. (for /f "usebackq delims=" %%s in (%srcF%) do (
  6. set "s=%%s" &(call :strLen s sL)
  7. set/a "n=!sL!-%fsL%","m+=1"
  8. for /L %%k in (0,1,!n!) do (
  9. set "sk=!s:~%%k,%fsL%!"
  10. (more +!m! %srcF%|findstr /i /c:"!sk!")>nul&&echo,!sk!
  11. )
  12. ))>%newF%
  13. endlocal&exit/b
  14. :strLen // %1为被测字符串变量名 %2为返回值变量名
  15. ( set "str=a!%~1!"
  16. set "len=0"
  17. for /l %%a in (12,-1,0) do (
  18. set/a "len|=1<<%%a"
  19. for %%b in (!len!) do if "!str:~%%b,1!"=="" set/a "len&=~1<<%%a"
  20.         )
  21. )
  22. if "%~2" neq "" set/a "%~2=!len!"
  23. exit /b
复制代码
二。P+js混编方案
  1. @set @v=1 /*
  2. @echo off
  3. set srcF="a.txt" &set newF="a.new"
  4. set/a "m=0","fsL=5" &::设置重复字段长度
  5. setlocal enabledelayedexpansion
  6. (for /f "usebackq delims=" %%s in (%srcF%) do (
  7. for /f "delims=" %%v in ('cscript /e:jscript "%~f0" "%%~s" ') do set "sL=%%v"
  8. set "s=%%s" &set/a "n=!sL!-%fsL%","m+=1"
  9. for /L %%k in (0,1,!n!) do (
  10. set "sk=!s:~%%k,%fsL%!"
  11. (more +!m! %srcF%|findstr /i /c:"!sk!")>nul&&echo,!sk!
  12. )
  13. ))>%newF%
  14. endlocal&exit/b
  15. */
  16. v=WSH.Arguments; //获取命令行参数
  17. WSH.Echo(v(0).length); //计算字符串长度
复制代码

作者: WHY    时间: 2022-10-14 23:19

回复 5# aloha20200628


    如果把 cscript 放到 for 循环体内部,每循环一次都要启动一个CMD 子进程,再调用一次 cscript
cscript本身执行命令的速度并不慢,但频繁启动 CMD 子进程、调用外部命令会花费很多时间,从而拖慢整个 bat 的执行时间。




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