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

[文本处理] 【已解决】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,结果为空
1

评分人数

    • Batcher: 感谢给帖子标题标注[已解决]字样PB + 2

这样可以不?
将代码保存为ANSI编码的bat,放在A.txt所在目录下运行,另外需要A.txt的编码为gbk,还有注意同次数的字符过多可能出错,循环65536次后会退出

也可以直接在命令行窗口输入
gawk -f 代码文件名 文本文件名
来查看所有的次数结果
  1. # 2>nul&cls&@echo off&set "file=A.txt"
  2. # 2>nul&for /f "tokens=1* delims= " %%a in ('gawk -f "%~f0" "%file%"') do set _%%a=%%b
  3. # 2>nul&setlocal enabledelayedexpansion
  4. # 2>nul&for /l %%a in (0,1,65535) do (echo,&set /p n=请输入N的值  N=&echo,&for %%a in ("!n!") do echo,!_%%~a!)
  5. # 2>nul&endlocal&pause&exit/b
  6. BEGIN{
  7. FS=" "
  8. while((getline <ARGV[1])>0){
  9. for(i=1;i<=NF;i++)
  10. A[$i]++
  11. }
  12. for(i in A){
  13. B[A[i]]=B[A[i]]?B[A[i]]" "i:i
  14. }
  15. for(i in B)print i,B[i]
  16. }
复制代码
1

评分人数

TOP

本帖最后由 思想之翼 于 2023-11-12 08:11 编辑

回复 2# Five66

感谢!
假如确定N=10(不用在运行界面输入),结果输出为文本B.txt,上述gawk代码如何简化?

TOP

练练手,用纯P试试:
  1. @echo off
  2. cd "D:\JZ"
  3. set N=10
  4. setlocal enabledelayedexpansion
  5. for /f "delims=" %%i in (a.txt) do (
  6.     for %%j in (%%i) do (
  7.         set /a _%%j+=1
  8.         if !_%%j! equ !N! (
  9.             set #%%j=true
  10.         ) else (
  11.             if !_%%j! gtr !N! set #%%j=
  12.         )
  13.     )
  14. )
  15. for /f "delims=#=" %%k in ('set #') do set str=!str! %%k
  16. if defined str echo,!str:~1!>b.txt
复制代码
1

评分人数

TOP

不知道行不
  1. awk -v RS='\r?\n| ' -v ORS=' ' '{++d[$0]}END{for(i in d){if(d[i]==1){print i}}}' a.txt
复制代码
2

评分人数

TOP

纯P好象不行,楼主的文件好象都是很大的

QQ 20147578

TOP

本帖最后由 qixiaobin0715 于 2023-11-12 09:56 编辑

回复 6# czjt1234
这与文件大小关系不大,只与相异字符总量有关,如果相异字符超过一定数量,可能会有问题。并且楼主在顶楼说的是“字母”,也就是26个而已,这样代码就不会设置更多变量。

TOP

本帖最后由 aloha20200628 于 2023-11-12 13:01 编辑


纯P求解字符重复数量的方案,还是采用变量名字典最为简捷,但有原生限制,例如不区分变量名字母大小写,例如文件每行字节长度受限8K。
针对一楼示例,每行均为大写字母且用系统默认分隔符,求其各字符的重复数量,代码如下》
  1. @echo off &setlocal enabledelayedexpansion
  2. for /f "delims=" %%s in (a.txt) do for %%c in (%%s) do if defined 【%%c】 (set/a "【%%c】+=1") else (set "【%%c】=1")
  3. set 【
  4. endlocal &exit/b
复制代码
类似变量名字典的纯P算法,再用jscript+cmd混编一个(存为*.cmd批处理脚本文件运行),可区分被统计字符的字母大小写。
  1. @set @v=1 /*
  2. @echo off
  3. cscript /e:jscript "%~f0" "a.txt" |sort
  4. pause &exit/b
  5. */
  6. var fso=new ActiveXObject('scripting.filesystemobject');
  7. var fr=fso.opentextfile(WSH.arguments(0)), lines=fr.readall().split('\r\n'); fr.close();
  8. var ln=lines.length, dc={};
  9. for (var k=0; k<ln; ++k) {
  10. var a=lines[k].split(''), an=a.length;
  11. for (var n=0; n<an; ++n) if (dc[a[n]]==undefined) dc[a[n]]=1; else dc[a[n]]++;
  12. }
  13. for (var key in dc) WSH.echo('字符: ' + key + ' 重复次数=' + dc[key]);
  14. WSH.quit();
复制代码
2

评分人数

TOP

回复 1# 思想之翼
  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"
复制代码
1

评分人数

TOP

本帖最后由 思想之翼 于 2023-11-12 20:00 编辑

回复 9# hfxiang
感谢!
文本是字母,正则表达式为 [A-Za-z]
文本是数值(例如:000 001...999,或00 01...99,或0 1...9),或者单个汉字(例如:挥 斥 方 遒 书 生 意 气),或者为词组(例如:挥斥方遒 书生意气),皆以空格间隔,正则表达式如何表达?

TOP

回复 10# 思想之翼

如果都以空格分隔,则无须考虑正则表达式,参照5楼的指令即可:
  1. 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"
复制代码
1

评分人数

TOP

返回列表