如何打印匹配的正则表达式模式使用 awk?

使用 awk,我需要在匹配正则表达式模式的文件中找到一个单词。

只有要打印的单词匹配的模式。

因此,如果在这条线上,我有:

xxx yyy zzz

模式:

/yyy/

我只想得到:

yyy

编辑: 多亏了 库鲁米,我终于写出了这样的东西:

awk '{
for(i=1; i<=NF; i++) {
tmp=match($i, /[0-9]..?.?[^A-Za-z0-9]/)
if(tmp) {
print $i
}
}
}' $1

这就是我需要的:)非常感谢!

568292 次浏览

这是最基本的

awk '/pattern/{ print $0 }' file

要求 awk使用 //搜索 pattern,然后打印出该行,默认情况下称为记录,用 $0表示。至少读读 文件

如果您只想打印出匹配的单词。

awk '{for(i=1;i<=NF;i++){ if($i=="yyy"){print $i} } }' file

这听起来像是您在试图模仿 GNU 的 grep -o行为。如果你只想要每行上的第一个匹配项:

awk 'match($0, /regex/) {
print substr($0, RSTART, RLENGTH)
}
' file

下面是一个使用 GNU 的 awk实现()的示例:

awk 'match($0, /a.t/) {
print substr($0, RSTART, RLENGTH)
}
' /usr/share/dict/words | head
act
act
act
act
aft
ant
apt
art
art
art

阅读 awk手册中的 matchsubstrRSTARTRLENGTH

之后,您可能希望扩展此函数来处理同一行上的多个匹配。

如果您只对输入的最后一行感兴趣,并且希望只找到一个匹配项(例如 shell 命令汇总行的一部分) ,您也可以尝试这段非常紧凑的代码,它采用自 如何使用‘ awk’打印 regexp 匹配?:

$ echo "xxx yyy zzz" | awk '{match($0,"yyy",a)}END{print a[0]}'
yyy

或者更复杂的版本,只有部分结果:

$ echo "xxx=a yyy=b zzz=c" | awk '{match($0,"yyy=([^ ]+)",a)}END{print a[1]}'
b

警告: 带有三个参数的 awk match()函数只存在于 gawk中,而不存在于 mawk

这里是另一个很好的解决方案,使用 grep中的 往正则表达式后面看而不是 awk。此解决方案对安装的要求较低:

$ echo "xxx=a yyy=b zzz=c" | grep -Po '(?<=yyy=)[^ ]+'
b

Gawk 可以使用以下动作获取每行的匹配部分:

{ if (match($0,/your regexp/,m)) print m[0] }

Match (string,regexp [ ,array ]) 如果数组存在,则清除它, 然后将数组的第零个元素设置为 如果 regexp 包含括号,则 数组的整数索引元素设置为包含 匹配对应的括号化子表达式的字符串。 Http://www.gnu.org/software/gawk/manual/gawk.html#string-functions

如果 Perl 是一个选项,您可以尝试这样做:

perl -lne 'print $1 if /(regex)/' file

要实现不区分大小写的匹配,请添加 i修饰符

perl -lne 'print $1 if /(regex)/i' file

比赛结束后打印所有东西:

perl -lne 'if ($found){print} else{if (/regex(.*)/){print $1; $found++}}' textfile

打印火柴和火柴后的所有东西:

perl -lne 'if ($found){print} else{if (/(regex.*)/){print $1; $found++}}' textfile

在这种情况下,使用 sed 也可以非常优雅。示例(用行中匹配的组“ yyy”替换行) :

$ cat testfile
xxx yyy zzz
yyy xxx zzz
$ cat testfile | sed -r 's#^.*(yyy).*$#\1#g'
yyy
yyy

相关手册页: https://www.gnu.org/software/sed/manual/sed.html#Back_002dreferences-and-Subexpressions

偏离主题,这也可以使用 grep 来完成,只需将其发布在这里,以防有人正在寻找 grep 解决方案

echo 'xxx yyy zzze ' | grep -oE 'yyy'

如果您知道要查找的文本/模式所在的列(例如“ yyy”) ,只需检查特定的列,看它是否匹配,然后打印出来。

例如,给定一个包含以下内容的文件(称为 ASDF.txt)

xxx yyy zzz

只打印符合“ yyy”模式的第二列,你可以这样做:

awk '$2 ~ /yyy/ {print $2}' asdf.txt

请注意,这也将基本上匹配第二列中有“ yyy”的任何行,如下所示:

xxx yyyz zzz
xxx zyyyz
echo "abc123def" | awk '


function MATCH(haystack, needle, ltrim, rtrim)
{
if(ltrim == 0 && !length(ltrim))
ltrim = 0;


if(rtrim == 0 && !length(rtrim))
rtrim = 0;


return substr(haystack, match(haystack, needle) + ltrim, RLENGTH - ltrim - rtrim);
}
    

{
print $0 " - " MATCH($0, "123");             # 123
print $0 " - " MATCH($0, "[0-9]*d", 0, 1);   # 123
print $0 " - " MATCH($0, "1234");            # Nothing printed
}'