仅在 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)
字段,没有 [
和 ]
个字符。
尝试编写正则表达式来捕获给定的字母数字值,但它也捕获其他数值。获得期望输出的正确方法应该是什么?
代码
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)
字段,没有[
和]
个字符。