找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 11271|回复: 13

[文本处理] 【已解决】gawk:如何提取指定个数范围的字符

[复制链接]
发表于 2024-12-1 02:50:06 | 显示全部楼层 |阅读模式
本帖最后由 思想之翼 于 2024-12-1 10:19 编辑

D:\JZ\A.txt  每行记录若干字符,格式如下:
G B B
B C C C A
J A
J
E
E D

【问题】如何用gawk,提取指定个数范围N的字符?
若指定N=2,结果为J A E
若指定N=3,结果为B C
若指定N=4,结果为空
若指定N=2、3,结果为J A E B C
若指定N=2、4,结果为J A E
若指定N=2、3、4,结果为J A E B C

下列代码,只能提取指定个数N=2的字符
  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"
复制代码

评分

参与人数 1PB +2 收起 理由
Batcher + 2 感谢给帖子标题标注[已解决]字样

查看全部评分

发表于 2024-12-1 05:18:44 | 显示全部楼层
不知行否 ,任意非数字分割 ,输出无序

  1. gawk -v"N=2,3、4" -v"RS=\r?\n| " -v"ORS= " "{++d[$0]}END{split(N,M,/[^0-9]+/);for(j in M){for(i in d)if(d[i]==M[j])print i}}" "D:\JZ\A.txt">"D:\JZ\B.txt"
复制代码

评分

参与人数 1技术 +1 收起 理由
思想之翼 + 1 感谢分享

查看全部评分

 楼主| 发表于 2024-12-1 10:47:42 | 显示全部楼层
回复 2# Five66

感谢帮助!结果正确。若N=50-100,共有51个数值,如何简洁表达?
发表于 2024-12-1 11:04:04 | 显示全部楼层
回复 3# 思想之翼

  1. gawk -v"N=50-100" -v"RS=\r?\n| " -v"ORS= " "{++d[$0]}END{split(N,M,/-/);for(j=M[1];j<=M[2];j++){for(i in d)if(d[i]==j)print i}}" "D:\JZ\A.txt">"D:\JZ\B.txt"
复制代码

评分

参与人数 1技术 +1 收起 理由
思想之翼 + 1 感谢分享

查看全部评分

 楼主| 发表于 2024-12-1 11:25:14 | 显示全部楼层
本帖最后由 思想之翼 于 2024-12-1 11:26 编辑

回复 4# hfxiang

感谢帮助!结果正确。再请教细节问题:若N=50-70,74,78,94-96,98,100,如何简洁设置?
发表于 2024-12-1 13:11:30 | 显示全部楼层
本帖最后由 hfxiang 于 2024-12-1 13:48 编辑

回复 5# 思想之翼

  1. gawk -v"N=40,50-70,74,78,94-96,98,100" -v"RS=\r?\n| " -v"ORS= " "{++d[$0]}END{split(N,M,/[^0-9]+/,s);A[M[1]];for(j in s){if(s[j]=="-"){for(i=M[j];i<=M[j+1];i++)A[i]}else{A[M[j+1]]}};for(j in A){for(i in d)if(d[i]==j)print i}}" "D:\JZ\A.txt">"D:\JZ\B.txt"
复制代码

评分

参与人数 1技术 +1 收起 理由
思想之翼 + 1 乐于助人

查看全部评分

 楼主| 发表于 2024-12-1 16:56:09 | 显示全部楼层
本帖最后由 思想之翼 于 2024-12-1 17:03 编辑

回复 2# Five66
感谢!结果正确。
 楼主| 发表于 2024-12-1 17:14:58 | 显示全部楼层
回复 6# hfxiang
感谢!结果正确。加入下列变量,运行出错,是正则表达式[^0-9]的原因吗?如何处置?
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /l %%d in (1,1,2) do (
  4. set o=%%d
  5. gawk -v"N=40,50-70,74,78,94-96,98,100" -v"RS=\r?\n| " -v"ORS= " "{++d[$0]}END{split(N,M,/[^0-9]+/,s);A[M[1]];for(j in s){if(s[j]=="-"){for(i=M[j];i<=M[j+1];i++)A[i]}else{A[M[j+1]]}};for(j in A){for(i in d)if(d[i]==j)print i}}" "D:\JZ1\!o!.txt">"D:\JZ2\!o!.txt"
  6. )
  7. endlocal
  8. exit
复制代码
发表于 2024-12-1 17:23:21 | 显示全部楼层
回复 8# 思想之翼
经套用脚本测试,/[^0-9]+/没问题,你能确定如下文件确实存在?
"D:\JZ1\!o!.txt" "D:\JZ2\!o!.txt"
 楼主| 发表于 2024-12-1 18:02:29 | 显示全部楼层
本帖最后由 思想之翼 于 2024-12-1 18:03 编辑

回复 9# hfxiang

感谢关注!不知道问题出在哪?

运行下列代码,结果正确:
  1. gawk -v"N=2,4,13,40,50-70,74,78,94-96,98,100" -v"RS=\r?\n| " -v"ORS= " "{++d[$0]}END{split(N,M,/[^0-9]+/,s);A[M[1]];for(j in s){if(s[j]=="-"){for(i=M[j];i<=M[j+1];i++)A[i]}else{A[M[j+1]]}};for(j in A){for(i in d)if(d[i]==j)print i}}" D:\JZ1\1.txt > D:\JZ2\1.txt]
复制代码
运行下列代码,不输出文本:
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /l %%d in (1,1,2) do (
  4. set o=%%d
  5. gawk -v"N=2,4,13,40,50-70,74,78,94-96,98,100" -v"RS=\r?\n| " -v"ORS= " "{++d[$0]}END{split(N,M,/[^0-9]+/,s);A[M[1]];for(j in s){if(s[j]=="-"){for(i=M[j];i<=M[j+1];i++)A[i]}else{A[M[j+1]]}};for(j in A){for(i in d)if(d[i]==j)print i}}" D:\JZ1\!o!.txt > D:\JZ2\!o!.txt
  6. )
  7. endlocal
  8. exit
复制代码
测试文本 1.txt 2.txt 记录数值相同,格式如下:
G B B
B C C C
J A A  A A
J
E
E D
0000 0000 0000 0000 0000
0000 0000 0000 0000 0000
0000 0000 0000
发表于 2024-12-1 19:25:43 | 显示全部楼层
回复 10# 思想之翼
建立"D:\JZ1\1.txt"及"D:\JZ1\2.txt"文件,创建"D:\JZ2"文件夹后,用以下脚本调用gawk 4.1.0 ( http://bcn.bathome.net/tool/4.1.0/gawk.exe )测试完全正常

  1. @echo off
  2. for /l %%d in (1,1,2) do (
  3. gawk -v"N=2,4,13,40,50-70,74,78,94-96,98,100" -v"RS=\r?\n| " -v"ORS= " "{++d[$0]}END{split(N,M,/[^0-9]+/,s);A[M[1]];for(j in s){if(s[j]=="-"){for(i=M[j];i<=M[j+1];i++)A[i]}else{A[M[j+1]]}};for(j in A){for(i in d)if(d[i]==j)print i}}" "D:\JZ1\%%~d.txt" > "D:\JZ2\%%~d.txt"
  4. )
复制代码

评分

参与人数 1技术 +1 收起 理由
思想之翼 + 1 感谢分享

查看全部评分

发表于 2024-12-1 19:46:27 | 显示全部楼层
回复 8# 思想之翼


   开启延迟变量扩展,多了次预处理,改为  [^^0-9]

评分

参与人数 1技术 +1 收起 理由
思想之翼 + 1 乐于助人

查看全部评分

发表于 2024-12-1 20:26:37 | 显示全部楼层
本帖最后由 Five66 于 2024-12-1 20:45 编辑

回复 3# 思想之翼


    非范围数字任意非 - 符号分割(注意特殊字符) ,范围数字 - 符号分割
  1. gawk -v"N=2,4,13 40#50-70,74-,78,94-96/98,,100" -v"RS=\r?\n| " -v"ORS= " "{++d[$0]}END{split(N,L,/[0-9]+-[0-9]+|[0-9]+/,W);for(i in W){if(split(W[i],Z,/-/)>1){for(j=Z[1];j<=Z[2];j++)M[j]}else{M[W[i]]}};for(j in M){for(i in d)if(d[i]==j)print i}}" "D:\JZ\A.txt">"D:\JZ\B.txt"
复制代码

评分

参与人数 1技术 +1 收起 理由
思想之翼 + 1 感谢分享

查看全部评分

发表于 2024-12-1 22:59:32 | 显示全部楼层
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for %%i in (1-3,5-15,20) do (
  4.     set "s=%%i"
  5.     if "!s:-=!" NEQ "!s!" (
  6.         for /L %%j in (!s:-^= 1 !) do set "n=!n! %%j"
  7.     ) else (
  8.         set "n=!n! %%i"
  9.     )
  10. )
  11. gawk -v"RS=\\s+"  -v"ORS= " "{++d[$0]};END{split("!n:~1!",a);for(i in d)for(j in a)if(d[i]==a[j])print i}" 1.txt > 2.txt
  12. pause
复制代码

评分

参与人数 1技术 +1 收起 理由
思想之翼 + 1 感谢分享

查看全部评分

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-17 14:48 , Processed in 0.027122 second(s), 9 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表