Board logo

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

作者: 思想之翼    时间: 4 天前 02:50     标题: 【已解决】gawk:如何提取指定个数范围的字符

本帖最后由 思想之翼 于 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"
复制代码

作者: Five66    时间: 4 天前 05:18

不知行否 ,任意非数字分割 ,输出无序
  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"
复制代码

作者: 思想之翼    时间: 4 天前 10:47

回复 2# Five66

感谢帮助!结果正确。若N=50-100,共有51个数值,如何简洁表达?
作者: hfxiang    时间: 4 天前 11: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"
复制代码

作者: 思想之翼    时间: 4 天前 11:25

本帖最后由 思想之翼 于 2024-12-1 11:26 编辑

回复 4# hfxiang

感谢帮助!结果正确。再请教细节问题:若N=50-70,74,78,94-96,98,100,如何简洁设置?
作者: hfxiang    时间: 4 天前 13:11

本帖最后由 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"
复制代码

作者: 思想之翼    时间: 4 天前 16:56

本帖最后由 思想之翼 于 2024-12-1 17:03 编辑

回复 2# Five66
感谢!结果正确。
作者: 思想之翼    时间: 4 天前 17:14

回复 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
复制代码

作者: hfxiang    时间: 4 天前 17:23

回复 8# 思想之翼
经套用脚本测试,/[^0-9]+/没问题,你能确定如下文件确实存在?
"D:\JZ1\!o!.txt" "D:\JZ2\!o!.txt"
作者: 思想之翼    时间: 4 天前 18:02

本帖最后由 思想之翼 于 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
作者: hfxiang    时间: 4 天前 19:25

回复 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. )
复制代码

作者: 77七    时间: 4 天前 19:46

回复 8# 思想之翼


   开启延迟变量扩展,多了次预处理,改为  [^^0-9]
作者: Five66    时间: 4 天前 20:26

本帖最后由 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"
复制代码

作者: WHY    时间: 4 天前 22:59

  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
复制代码





欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2