标题: [文本处理] 【已解决】gawk:如何提取指定个数的字符 [打印本页]
作者: 思想之翼 时间: 2023-11-12 04:54 标题: 【已解决】gawk:如何提取指定个数的字符
本帖最后由 思想之翼 于 2023-11-12 20:46 编辑
D:\JZ\A.txt 每行记录若干字母,格式如下:
G B B
B C C C A
J A
J
E
E D
【问题】如何用gawk,提取A.txt出现N次的字符?
若指定个数的字符不存在,则输出文本为空。
上例N=2,结果为J A E
上例N=3,结果为B C
上例N=4,结果为空
作者: Five66 时间: 2023-11-12 07:08
这样可以不?
将代码保存为ANSI编码的bat,放在A.txt所在目录下运行,另外需要A.txt的编码为gbk,还有注意同次数的字符过多可能出错,循环65536次后会退出
也可以直接在命令行窗口输入
gawk -f 代码文件名 文本文件名
来查看所有的次数结果- # 2>nul&cls&@echo off&set "file=A.txt"
- # 2>nul&for /f "tokens=1* delims= " %%a in ('gawk -f "%~f0" "%file%"') do set _%%a=%%b
- # 2>nul&setlocal enabledelayedexpansion
- # 2>nul&for /l %%a in (0,1,65535) do (echo,&set /p n=请输入N的值 N=&echo,&for %%a in ("!n!") do echo,!_%%~a!)
- # 2>nul&endlocal&pause&exit/b
-
- BEGIN{
- FS=" "
- while((getline <ARGV[1])>0){
- for(i=1;i<=NF;i++)
- A[$i]++
- }
- for(i in A){
- B[A[i]]=B[A[i]]?B[A[i]]" "i:i
- }
- for(i in B)print i,B[i]
- }
复制代码
作者: 思想之翼 时间: 2023-11-12 07:36
本帖最后由 思想之翼 于 2023-11-12 08:11 编辑
回复 2# Five66
感谢!
假如确定N=10(不用在运行界面输入),结果输出为文本B.txt,上述gawk代码如何简化?
作者: qixiaobin0715 时间: 2023-11-12 09:12
练练手,用纯P试试:- @echo off
- cd "D:\JZ"
- set N=10
- setlocal enabledelayedexpansion
- for /f "delims=" %%i in (a.txt) do (
- for %%j in (%%i) do (
- set /a _%%j+=1
- if !_%%j! equ !N! (
- set #%%j=true
- ) else (
- if !_%%j! gtr !N! set #%%j=
- )
- )
- )
- for /f "delims=#=" %%k in ('set #') do set str=!str! %%k
- if defined str echo,!str:~1!>b.txt
复制代码
作者: wanghan519 时间: 2023-11-12 09:27
不知道行不- awk -v RS='\r?\n| ' -v ORS=' ' '{++d[$0]}END{for(i in d){if(d[i]==1){print i}}}' a.txt
复制代码
作者: czjt1234 时间: 2023-11-12 09:31
纯P好象不行,楼主的文件好象都是很大的
作者: qixiaobin0715 时间: 2023-11-12 09:53
本帖最后由 qixiaobin0715 于 2023-11-12 09:56 编辑
回复 6# czjt1234
这与文件大小关系不大,只与相异字符总量有关,如果相异字符超过一定数量,可能会有问题。并且楼主在顶楼说的是“字母”,也就是26个而已,这样代码就不会设置更多变量。
作者: aloha20200628 时间: 2023-11-12 10:54
本帖最后由 aloha20200628 于 2023-11-12 13:01 编辑
纯P求解字符重复数量的方案,还是采用变量名字典最为简捷,但有原生限制,例如不区分变量名字母大小写,例如文件每行字节长度受限8K。
针对一楼示例,每行均为大写字母且用系统默认分隔符,求其各字符的重复数量,代码如下》- @echo off &setlocal enabledelayedexpansion
- for /f "delims=" %%s in (a.txt) do for %%c in (%%s) do if defined 【%%c】 (set/a "【%%c】+=1") else (set "【%%c】=1")
- set 【
- endlocal &exit/b
复制代码
类似变量名字典的纯P算法,再用jscript+cmd混编一个(存为*.cmd批处理脚本文件运行),可区分被统计字符的字母大小写。- @set @v=1 /*
- @echo off
- cscript /e:jscript "%~f0" "a.txt" |sort
- pause &exit/b
- */
- var fso=new ActiveXObject('scripting.filesystemobject');
- var fr=fso.opentextfile(WSH.arguments(0)), lines=fr.readall().split('\r\n'); fr.close();
- var ln=lines.length, dc={};
- for (var k=0; k<ln; ++k) {
- var a=lines[k].split(''), an=a.length;
- for (var n=0; n<an; ++n) if (dc[a[n]]==undefined) dc[a[n]]=1; else dc[a[n]]++;
- }
- for (var key in dc) WSH.echo('字符: ' + key + ' 重复次数=' + dc[key]);
- WSH.quit();
复制代码
作者: hfxiang 时间: 2023-11-12 14:23
回复 1# 思想之翼 - gawk -v"N=2" -v"FS=" "{for(i=1;i<=NF;i++)if($i~/[A-Za-z]/)a[$i]++}END{for(i in a)if(a[i]==N)printf i\" \";ptint\"\"}" "D:\JZ\A.txt">"D:\JZ\B.txt"
复制代码
作者: 思想之翼 时间: 2023-11-12 19:54
本帖最后由 思想之翼 于 2023-11-12 20:00 编辑
回复 9# hfxiang
感谢!
文本是字母,正则表达式为 [A-Za-z]
文本是数值(例如:000 001...999,或00 01...99,或0 1...9),或者单个汉字(例如:挥 斥 方 遒 书 生 意 气),或者为词组(例如:挥斥方遒 书生意气),皆以空格间隔,正则表达式如何表达?
作者: hfxiang 时间: 2023-11-12 20:15
回复 10# 思想之翼
如果都以空格分隔,则无须考虑正则表达式,参照5楼的指令即可:- gawk -v"N=2" -v"RS=\r?\n| " -v"ORS= " "{++d[$0]}END{for(i in d)if(d[i]==N)print i}" "D:\JZ\A.txt">"D:\JZ\B.txt"
复制代码
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |