标题: [文本处理] [已解决]批处理如何删掉前面出现过的字所在行? [打印本页]
作者: 每天几分 时间: 2022-11-5 20:41 标题: [已解决]批处理如何删掉前面出现过的字所在行?
本帖最后由 每天几分 于 2022-11-7 12:59 编辑
有1个txt文件,全是词语,要实现每个字只能出现1次,后面如果出现前面出现过的,则删掉后面这行。
如:
一个
这个
但是
自己
就是
但我
还是
我们
自我
这不
很多
……
实现如下:
一个
但是
自己
很多- 就是说前面出了“一个”所以后面带“一……”、“……一”、“……个”、“个……”的行都删掉。
- 同样,前面出了“这是”,后面带“这……”“……这”“是……”“……是”的行都删掉。
复制代码
作者: pd1 时间: 2022-11-5 22:24
”我们“的“我”在上面有个”但我“
这个不算出现过了吗
如果不算出现过了 那么“这不”也应该在结果中吧。
文本保存在1.txt里。上面说的两种情况用以下两种代码。保存为.bat文件
另外现在win10和win11 新建的文本都是utf8格式的,就用了默认的- <# :
- @echo off
- powershell -NoProfile -ExecutionPolicy bypass "Get-Content -literal '%~f0' |Out-String|Invoke-Expression"
- pause
- #>
- $a=@()
- $b=@()
- gc -Encoding UTF8 .\1.txt |%{if((Compare-Object $b $_.ToCharArray() -PassThru -IncludeEqual -ExcludeDifferent).length -eq 0){$a+=$_;$_.ToCharArray()|%{$b+=$_}}}
- $a
复制代码
- <# :
- @echo off
- powershell -NoProfile -ExecutionPolicy bypass "Get-Content -literal '%~f0' |Out-String|Invoke-Expression"
- pause
- #>
- $a=@()
- $b=@()
- gc -Encoding UTF8 .\1.txt |%{if((Compare-Object $b $_.ToCharArray() -PassThru -IncludeEqual -ExcludeDifferent).length -eq 0){$a+=$_;$_.ToCharArray()|%{$b+=$_}}else{$_.ToCharArray()|%{$b+=$_}}}
- $a
复制代码
作者: 每天几分 时间: 2022-11-5 23:06
回复 2# pd1
算出现过,不好意思,是我打错了,你的第二个批处理可解决。
作者: 每天几分 时间: 2022-11-5 23:25
效率有点慢,词语一多就慢了,6000个就用了10分钟以上。
有200多万词啊
作者: qixiaobin0715 时间: 2022-11-6 08:49
如果每行只有2个字,这个应当勉强可用,想要更高效率还是期待大佬吧:- @echo off
- setlocal enabledelayedexpansion
- (for /f "delims=" %%a in (1.txt) do (
- set str=%%a
- echo,!str:~,1! !str:~-1!
- ))>temp.log
- (for /f "tokens=1*" %%i in (temp.log) do (
- if not defined _%%i if not defined _%%j echo,%%i%%j
- set /a _%%i=_%%j=1
- ))>out.txt
- del temp.log
- pause
复制代码
作者: pd1 时间: 2022-11-6 09:24
回复 4# 每天几分
慢是必然的,一行一行去对比的,每一行都把字拆散,效率就不是我能力范围了
作者: qixiaobin0715 时间: 2022-11-6 10:40
本帖最后由 qixiaobin0715 于 2022-11-6 10:47 编辑
还是要好好想想,逻辑上好像有点问题,比如:复制代码
是只要第一行,还是第一行和第三行都要。复杂了!!!
这种呢:复制代码
作者: 每天几分 时间: 2022-11-6 17:43
回复 7# qixiaobin0715
一个
这个
这是
是的
只要
一个
这是
因为前面出了“一个”所以后面带“一……”、“……一”、“……个”、“个……”的行都删掉。
同样,前面出了“这是”,后面带“这……”“……这”“是……”“……是”的行都删掉。
作者: hfxiang 时间: 2022-11-6 18:06
假设原文件为1.txt,编码格式为ANSI,去重用gawk( http://bcn.bathome.net/tool/4.1.0/gawk.exe ),效率也是杠杠的:- gawk "{ID=1;for(i=0;++i<=length($0);){if(a[substr($0,i,1)]++){ID=0}}if(ID)print}" 1.txt>2.txt
复制代码
作者: WHY 时间: 2022-11-6 22:41
本帖最后由 WHY 于 2022-11-8 11:13 编辑
- $srcFile = '1.txt';
- $dstFile = '2.txt';
- $Hash = @{};
- $out = [Collections.ArrayList]@();
-
- forEach( $str In [IO.File]::ReadAllLines($srcFile, [Text.Encoding]::Default) ){
- $flag = $True;
- for( $i=0; $i -lt $str.Length; $i++ ){
- if( $Hash.Contains($str[$i]) ){ $flag = $False; break; }
- }
- if( $flag ){
- $null = $out.Add($str);
- for( $i=0; $i -lt $str.Length; $i++ ){
- if( !$Hash.Contains($str[$i]) ){ $Hash.Add( $str[$i], $True ); }
- }
- }
- }
-
- [IO.File]::WriteAllLines($dstFile, $out, [Text.Encoding]::Default);
-
- echo 'Done';
- [Console]::ReadLine();
复制代码
作者: qixiaobin0715 时间: 2022-11-7 08:37
本帖最后由 qixiaobin0715 于 2022-11-7 08:46 编辑
回复 8# 每天几分
这个与你顶楼的例子好像有差异。
开始没仔细看,被你在顶楼的描述带偏了,5楼代码逻辑上有问题,如果想使用纯批处理代码,可以运行下面代码,因为你没有提供文件样本,无法测试,个人感觉效率上还过得去:- @echo off
- setlocal enabledelayedexpansion
- (for /f "delims=" %%a in (1.txt) do (
- set str=%%a
- if not defined _"!str:~,1!" if not defined _"!str:~-1!" (
- echo,%%a
- set _"!str:~,1!"=true
- set _"!str:~-1!"=true
- )
- ))>out.txt
- pause
复制代码
作者: hfxiang 时间: 2022-11-7 08:40
(gawk.exe 的下载地址见 9 楼)
方案一:按楼主的需求以输入文件去重出结果- gawk "{ID=1;for(i=0;++i<=length($0);){s=substr($0,i,1);if(!b[s]++)if(a[s]++)ID=0}delete b}ID" 1.txt>2.txt
-
- 结果:
- 一个
- 但是
- 自己
- 很多
复制代码
方案二:以输出文件去重出结果(输出结果在不同的行不会出现重复字,本人觉得这个看上去好像更合理)- gawk "{ID=1;for(i=0;++i<=length($0);){s=substr($0,i,1);if(!b[s]++)if(s in a)ID=0}if(ID){for(i=0;++i<=length($0);)a[substr($0,i,1)];print}delete b}" 1.txt>2.txt
-
- 结果:
- 一个
- 但是
- 自己
- 我们
- 这不
- 很多
复制代码
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |