标题: [文本处理] 【已解决】如何用第三方工具,比较统计两文本的字符记录次数 [打印本页]
作者: 思想之翼 时间: 前天 02:48 标题: 【已解决】如何用第三方工具,比较统计两文本的字符记录次数
本帖最后由 思想之翼 于 2024-12-3 16:45 编辑
D:\DATA\1.txt 记录字符:
中国 中国 中国 美国
欧盟 法国 法国 德国
D:\DATA\2.txt 记录字符:
中国 美国 美国
法国 法国 法国 法国
英国 德国
现在欲用第三方工具,比较统计上述两文本的字符记录次数。
分析上例:
中国:1.txt记录3次,2.txt记录1次
美国:1.txt记录1次,2.txt记录2次
欧盟:1.txt记录1次,2.txt记录0次
德国:1.txt记录1次,2.txt记录1次
英国:1.txt记录0次,2.txt记录1次
法国:1.txt记录2次,2.txt记录4次
1.txt 比 2.txt 记录次数多的字符为 中国 欧盟 ,写入D:\DATA\A.txt
2.txt 比 1.txt 记录次数多的字符为 美国 英国 法国,写入D:\DATA\B.txt
1.txt 与 2.txt 记录次数相同的字符为 德国,写入D:\DATA\C.txt
最终输出结果:
A.txt
中国 欧盟
B.txt
美国 英国 法国
C.txt
德国
【注】下列代码,分别统计1.txt 与 2.txt的字符个数:- gawk "{for(i=1;i<=NF;i++)a[$i]++}END{for(j in a)print j,a[j]}" 1.txt>统计1.txt
- gawk "{for(i=1;i<=NF;i++)a[$i]++}END{for(j in a)print j,a[j]}" 2.txt>统计2.txt
复制代码
结果:
统计1.txt
德国 1
美国 1
法国 2
欧盟 1
中国 3
统计2.txt
英国 1
德国 1
美国 2
法国 4
中国 1
作者: qixiaobin0715 时间: 前天 08:53
不用第三方也可,有点文不对题:- @echo off
- for /f "delims=" %%i in (1.txt) do (
- for %%j in (%%i) do (
- set _%%j=true
- set /a @%%j+=1
- )
- )
- for /f "delims=" %%i in (2.txt) do (
- for %%j in (%%i) do (
- set _%%j=true
- set /a #%%j+=1
- )
- )
- setlocal enabledelayedexpansion
- for /f "delims=_=" %%i in ('set _') do (
- if not defined @%%i set @%%i=0
- if not defined #%%i set #%%i=0
- if !@%%i! gtr !#%%i! (
- set a=!a!%%i
- ) else if !@%%i! lss !#%%i! (
- set b=!b!%%i
- ) else (
- set c=!c!%%i
- )
- )
- for %%i in (a b c) do echo,!%%i!>%%i.txt
- pause
复制代码
权当自己练练手,这个就不要评分了。
作者: hfxiang 时间: 前天 13:40
回复 1# 思想之翼
请确保1.txt及2.txt已以ansi编码保存,用gawk( http://bcn.bathome.net/tool/4.1.0/gawk.exe )在命令行窗口中实现方式如下:- gawk -v"RS=\r?\n| " "{++a[$0][FILENAME];f[FILENAME]}END{PROCINFO[\"sorted_in\"]=\"@ind_str_desc\";for(i in a)for(j in f)if(!a[i][j]){};for(i in a){printf i;s=1;for(j in a[i]){sId=s?\":\":\",\";printf sId\" %s 记录 %d 次\",j,a[i][j];s=0}print\"\"}}" 1.txt 2.txt>3.txt
复制代码
如果1.txt及2.txt是以UTF-8编码保存,则可用RUBY( https://github.com/oneclick/ruby ... kit-3.3.6-2-x64.exe )中的gawk来处置
作者: 思想之翼 时间: 前天 14:39
本帖最后由 思想之翼 于 2024-12-3 14:58 编辑
回复 3# hfxiang
感谢!代码对比分析的中间结果正确,学习了。
1#表述重点不突出,所需的最终结果没有突出显示,以至让您疏忽了。
分析上例:
中国:1.txt记录3次,2.txt记录1次
美国:1.txt记录1次,2.txt记录2次
欧盟:1.txt记录1次,2.txt记录0次
德国:1.txt记录1次,2.txt记录1次
英国:1.txt记录0次,2.txt记录1次
法国:1.txt记录2次,2.txt记录4次
1.txt 比 2.txt 记录次数多的字符为 中国 欧盟 ,写入D:\DATA\A.txt
2.txt 比 1.txt 记录次数多的字符为 美国 英国 法国,写入D:\DATA\B.txt
1.txt 与 2.txt 记录次数相同的字符为 德国,写入D:\DATA\C.txt
最终输出结果:
A.txt
中国 欧盟
B.txt
美国 英国 法国
C.txt
德国
作者: aloha20200628 时间: 前天 15:42
本帖最后由 aloha20200628 于 2024-12-3 22:21 编辑
回复 1# 思想之翼
批处调用 findstr 可以拿下,代码量略多》先构建每个目标文件(d:\data\1.txt, d:\data\2.txt)对应的变量字典,再相互比对每本字典的键名及其键值,导出三个结果列表(a.txt, b.txt, c.txt)...- @echo off &cd /d "d:\data" &del /q "a.txt", "b.txt", "c.txt" 2>nul
- setlocal &set "F1=1.txt" &set "F2=2.txt"
- (call :xx "%F1%") & (call :xx "%F2%")
- (for /f "delims=" %%a in ('findstr /vig:"_%F1%.0" "_%F2%.0" ') do set/p="%%a "<nul)>"b.txt"
- (for /f "delims=" %%a in ('findstr /vig:"_%F2%.0" "_%F1%.0" ') do set/p="%%a "<nul)>"a.txt"
- for /f "usebackq tokens=1,2 delims==" %%a in ("_%F1%.1") do (
- for /f "tokens=1,2 delims==" %%x in ('findstr /lic:"%%~a" "_%F2%.1" ') do if %%b equ %%y (set/p="%%a "<nul>>"c.txt") else if %%b gtr %%y (set/p="%%a "<nul>>"a.txt") else (set/p="%%a "<nul>>"b.txt")
- )
- del/q "_%F1%.?" "_%F2%.?"&pause&exit/b
- :xx
- setlocal enabledelayedexpansion
- for /f "usebackq delims=" %%a in ("%~1") do for %%x in (%%a) do if defined _%%x (set/a "_%%x+=1") else (set "_%%x=1" &set "all=!all!,_%%x")
- (for %%a in (!all!) do set "a=%%a"&echo,!a:~1!)>"_%~1.0"
- (for %%a in (!all!) do set "a=%%a"&echo,!a:~1!=!%%a!)>"_%~1.1"
- endlocal&exit/b
复制代码
作者: hfxiang 时间: 前天 16:13
本帖最后由 hfxiang 于 2024-12-3 16:44 编辑
回复 4# 思想之翼 - gawk -v"RS=\r?\n| " "FNR==1{fn[++n]=FILENAME}{++a[$0][fn[n]]}END{for(i in a){if(a[i][fn[1]]>a[i][fn[2]]){printf\"%s \",i>\"A.txt\"}else if(a[i][fn[1]]<a[i][fn[2]]){printf\"%s \",i>\"B.txt\"}else{printf\"%s \",i>\"C.txt\"}}}" 1.txt 2.txt
复制代码
作者: 77七 时间: 前天 17:26
- @echo off
- cd /d "D:\DATA\"
- if "%~1" equ "" (
- setlocal enabledelayedexpansion
- for /f "tokens=1-2" %%a in ('%0 # ^| sort ^& echo 1 1') do (
- if "!str!" neq "%%a" (
- if defined str (
- set /a m=#!str!
- if !m! gtr 0 (
- >>a.txt echo !str!
- ) else if !m! equ 0 (
- >>c.txt echo !str!
- ) else (
- >>b.txt echo !str!
- )
- )
- set str=%%a
- )
- set /a #!str!+=%%b
- )
- endlocal
- pause
- exit
- ) else (
- for %%i in ("1.txt|1" "2.txt|-1") do (
- for /f "tokens=1-2 delims=|" %%j in ("%%~i") do (
- for /f "useback delims=" %%a in ("%%j") do (
- for %%b in (%%a) do (
- echo %%b %%k
- )
- )
- )
- )
- )
复制代码
作者: aloha20200628 时间: 前天 20:05
本帖最后由 aloha20200628 于 2024-12-3 20:16 编辑
回复 1# 思想之翼
用5楼的算法复刻一个 bat+powershell 版本,以下代码存为 test.bat 运行,结果会在 d:\data 目录中产生 a.txt, b.txt, c.txt 三个文件...- <# ::
- @echo off &cd /d "d:\data" &powershell "iex(${%~f0}|out-string)" &pause&exit/b
- #>
- $h1=@{}; gc 1.txt|%{foreach($i in $_.split()){if($h1.containsKey($i)){$h1[$i]+=1}else{$h1.add($i,1)}}}
- $h2=@{}; gc 2.txt|%{foreach($i in $_.split()){if($h2.containsKey($i)){$h2[$i]+=1}else{$h2.add($i,1)}}}
- $a=$b=$c=''; $h1.keys|%{if(!$h2.containsKey($_)){$a+=$_+' '}}; $h2.keys|%{if(!$h1.containsKey($_)){$b+=$_+' '}};
- $h1.keys|%{if($h2.containsKey($_)){if($h1[$_] -eq $h2[$_]){$c+=$_+' '}elseif($h1[$_] -gt $h2[$_]){$a+=$_+' '}else{$b+=$_+' '}}}
- sc a.txt $a.trimend(); sc b.txt $b.trimend(); sc c.txt $c.trimend(); exit
复制代码
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |