regex 用于捕获AWK中具有一个数字范围的数字的正则表达式

vq8itlhq  于 2022-11-18  发布在  其他
关注(0)|答案(5)|浏览(107)

我试图捕捉一个文件内的数字使用AWK,我可以捕捉所有,但我不能捕捉那些在一定数量的数字。我做错了什么?
echo -e "$teste" | awk '/_OA/ { match($0,/\[\([:digit:]{4,13}\]/);oa = substr($0,RSTART,RLENGTH);print oa}'
文件示例:

_OA ............. [6712227000168]
_OA Tasdsd, OA .. [91][355016]
_OA Tasdsd, DA .. [91][5512987000]

预期值:

6712227000168
355016
5512987000

正则表达式匹配答案提示:非常感谢所有的答案,我发现link,我需要使用一个**--posix**选项,因为我的awk版本。

w6lpcovy

w6lpcovy1#

使用您所示的示例,请尝试以下awk解决方案。只需将字段分隔符设置为] OR [,并在主块检查条件下,如果行从_QA开始,则打印倒数第二个字段。

awk -F"[][]" '/^_QA /{print $(NF-1)}'  Input_file
cbwuti44

cbwuti442#

您可以更新RSTART和RLENGTH的模式和值,使其与前导方括号和尾随方括号不匹配。
数字部分应为[[:digit:]],但模式中有一个\(与不应存在的(匹配。

awk '/_OA/ { match($0,/\[[[:digit:]]{4,13}\]/);oa = substr($0,RSTART+1,RLENGTH-2);print oa}' <<< "$teste"

输出量

6712227000168
355016
5512987000

由于方括号中的数字多次出现,如果要匹配多次出现的数字:

teste='_OA Tasdsd, OA .. [91][355016][123456789][1][9999]'

awk '/_OA/ {
  while(match($0,/\[[[:digit:]]{4,13}]/)){
    start=RSTART+1; len=RLENGTH-2
    s=substr($0,start,len)
    res=res?res","s:s    
    $0=substr($0,start+len)
  }
  print res
  res = ""
}' <<< "$teste"

输出量

355016,123456789,9999
5w9g7ksd

5w9g7ksd3#

您的正则表达式\[\([:digit:]{4,13}\]表示:

  1. \[ =文字字符[
  2. \( =文字字符(
  3. [:digit:] =包含字符:digt的字符集的括号表达式
  4. {4,13} =一个正则表达式间隔,它是前面的括号表达式的4到13次重复
  5. \] =文字字符]
    导致regexp无法匹配任何输入的两个主要问题是:
    1.您的输入中没有任何((来自上面的#2),并且
    1.要匹配数字,您需要在括号表达式[[:digit:]]中使用字符类[:digit:],而不是在括号表达式[:digit:]中使用字符集:digit:(来自上面的#3)
    实际上,您也不需要对regexp末尾的]进行转义,因为如果前面是匹配的未转义[(括号表达式的开头),则它只是一个regexp元字符(括号表达式的结尾)。
    所以我想你想写的正则表达式应该是:
\[[[:digit:]]{4,13}]

例如:

$ awk '/_OA/ { match($0,/\[[[:digit:]]{4,13}]/);oa = substr($0,RSTART,RLENGTH);print oa}' file
[6712227000168]
[355016]
[5512987000]

或仅打印数字:

$ awk '/_OA/ { match($0,/\[[[:digit:]]{4,13}]/);oa = substr($0,RSTART+1,RLENGTH-2);print oa}' file
6712227000168
355016
5512987000
b5lpy0ml

b5lpy0ml4#

如果你没有嫁给awk:

grep -Eo '[[:digit:]]{4,13}'

使用GNU awk:

gawk 'match($0, /[[:digit:]]{4,13}/, m) {print m[0]}'

但这只匹配每个记录中的第一个此类编号。要查找所有编号,请执行以下操作:

gawk '{
    line = $0
    while (match(line, /[[:digit:]]{4,13}/, m)) {
        print m[0]
        line = substr(line, m[0,"start"] + m[0,"length"])
    }
}'

请参考gawk手册中的match函数。

uyhoqukh

uyhoqukh5#

您可以使用

awk '/_OA/ { match($0,/\[[[:digit:]]{4,13}]/);print substr($0,RSTART+1,RLENGTH-2)}'

请参阅online demo

#!/bin/bash
s='_OA ............. [6712227000168]
_OA Tasdsd, OA .. [91][355016]
_OA Tasdsd, DA .. [91][5512987000]'
awk '/_OA/ { match($0,/\[[[:digit:]]{4,13}]/);print substr($0,RSTART+1,RLENGTH-2)}' <<< "$s"

输出量:

6712227000168
355016
5512987000

详细数据

  • \[-一个[字符
  • [[:digit:]]{4,13}-4到13位数字(请注意,[:digit:] POSIX字符类必须在[...]中使用,[...]是一个括号表达式)
  • ]-一个]字符(不是特殊字符,无需转义)

substr($0,RSTART+1,RLENGTH-2)意味着我们

  • $0-拿下比赛
  • RSTART+1-从第二个字符开始
  • RLENGTH-2-然后是与匹配长度一样多的字符- 2(这样就去掉了封闭的[]字符)

相关问题