仅在 shell 中捕获字母数字字符串的正则表达式

Regular expression to capture alphanumeric string only in shell

尝试编写正则表达式来捕获给定的字母数字值,但它也捕获其他数值。获得期望输出的正确方法应该是什么?

代码

grep -Eo '(\[[[:alnum:]]\)\w+' file > output
$ cat file
2022-04-29 08:45:11,754 [14] [Y23467] [546] This is a single line
2022-04-29 08:45:11,764 [15] [fpes] [547] This is a single line
2022-04-29 08:46:12,454 [143] [mwalkc] [548] This is a single line
2022-04-29 08:49:12,554 [143] [skhat2] [549] This is a single line
2022-04-29 09:40:13,852 [5] [narl12] [550] This is a single line
2022-04-29 09:45:14,754 [1426] [Y23467] [550] This is a single line

当前输出-

[14
[Y23467
[546
[15
[fpes
[547
[143
[mwalkc
[548
[143
[skhat2
[549
[5
[narl12
[550
[1426
[Y23467
[550

预期输出 -

Y23467
fpes
mwalkc
skhat2
narl12
Y23467

第一个解决方案: 使用您显示的示例,请尝试遵循 awk 代码。简单的解释是,使用 gsub 函数替换第 4 个字段中的 [],然后打印第 4 个字段。

awk '{gsub(/\[|\]/,"",);print }' Input_file


第二个解决方案: 使用 GNU grep 请尝试以下解决方案。

grep -oP '^[0-9]{4}(-[0-9]{2}){2} [0-9]{2}(:[0-9]{2}){2},[0-9]{1,3} \[[0-9]+\] \[\K[^]]*' Input_file

说明: 为 GNU grep.

中使用的上述正则表达式添加详细说明
^[0-9]{4}(-[0-9]{2}){2}  ##From starting of value matching 4 digits followed by dash 2 digits combination of 2 times.
 [0-9]{2}(:[0-9]{2}){2}  ##Matching space followed by 2 digits followed by : 2 digits combination of 2 times.
,[0-9]{1,3}              ##Matching comma followed by digits from 1 to 3 number.
 \[[0-9]+\] \[\K         ##Matching space followed by [ digits(1 or more occurrences of digits) followed by space [ and
                         ##then using \K to forget all the previously matched values.
[^]]*                    ##Matching everything just before 1st occurrence of ] to get actual values.

使用sed

$ sed 's/\([^[]*\[\)\{2\}\([^]]*\).*//' input_file
Y23467
fpes
mwalkc
skhat2
narl12
Y23467

使用[[:alnum:]]\w意味着它可能匹配字母数字或单词字符。

如果可以有数字,但应该有一个字符 a-z 并且支持使用 -P 作为 perl 兼容的正则表达式:

grep -oP '\[\K\d*[A-Za-z][\dA-Za-z]*(?=])' file

说明

  • \[ 匹配 [
  • \K忘记目前匹配的是什么
  • \d*[A-Za-z] 匹配可选数字和至少一个字符 a-zA-Z
  • [\dA-Za-z]* 匹配可选字符 a-zA-Z 和数字
  • (?=]) 向右断言 ]

输出

Y23467
fpes
mwalkc
skhat2
narl12
Y23467

如果只能出现 1 次,您还可以将 sed 与捕获组 \(...\) 一起使用,并使用 </code></p> 在替换中使用该组 <pre><code>sed 's/.*\[\([[:digit:]]*[[:alpha:]][[:alnum:]]*\)].*//' file

您的问题有几个部分。首先,我将尝试帮助您处理正则表达式(但它可能会解决更多问题);接下来我会告诉你一个替代方案。

正则表达式

关于 [[:alnum:]] 需要了解的是,它捕获任何包含字母数字字符的内容。所以它会捕获“123”,它会捕获“abc”,因为所有这些字符都是字母数字。它会单独判断每个字符,无法像您想要的那样捕获“仅包含数字和字母的部分”。

但是,通过将几个 grep 链接在一起,我们可以过滤掉仅包含数字的行。

grep -Eo '(\[[[:alnum:]]\)\w+' file | grep -v -Eo '\[[[:digit:]]+(\w+|$)' > output

为了进一步改进,您的正则表达式中似乎存在一些错误。首先,您已将 \[ 包含在捕获的部分中,这就是它在结果中捕获 [ 的原因,因此您应该将 (\[ 更改为 \[( 以移动 [ 在括号中捕获的部分之外 ( ... ).

接下来,您的 [[:alnum:]]\w+ 的组合可能不会达到您的预期。它寻找一个字母数字字符,后跟一个或多个“单词”字符(即所有字母数字,加上一些额外的字符)。你可能想要 ([[:alnum:]]+) 而不是 ([[:alnum:]])\w+

备选

为什么不使用 cut 呢? cut -d' ' -f4 将取第 4 个字段(以“space”作为字段之间的分隔符)

$ cut -d' ' -f 4 file 
[Y23467]
[fpes]
[mwalkc]
[skhat2]
[narl12]
[Y23467]

如果您还想删除方括号,请尝试

$ cut -d' ' -f 4 file | grep -Eo '\w+'
Y23467
fpes
mwalkc
skhat2
narl12
Y23467

FPAT 与 GNU awk 结合使用:

awk -v FPAT='[[[:alnum:]]*]' '{gsub(/^\[|\]$/, "",$(NF-1));print $(NF-1)}' file
Y23467
fpes
mwalkc
skhat2
narl12
Y23467
  • 设置 FPAT'[[[:alnum:]]*]' 我们匹配 [ 字符后跟零或更多字母数字字符后跟 ] 字符。

  • 使用 gsub() 函数我们删除初始 [ 和最终 ] 个字符。

  • 我们打印最后一个字段之前的字段,即 $(NF-1) 字段,没有 [] 个字符。