2011-04-04 65 views
60

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

我只有想打印与模式匹配的单词。

因此,如果行,我有:

xxx yyy zzz 

而且图案:

/yyy/ 

我只想得到:

yyy 

编辑: 感谢到ku鲁米我设法写的是这样的:

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

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

+2

我读到这,这太古怪了我:S – marverix 2011-04-04 08:17:19

+2

那么我会建议你提供一点点你的任务细节。它太含糊。 – 2011-04-04 08:20:36

+0

@maxtaldykin你可以将你的自我回答从问题转移到单独的答案吗? – kenorb 2018-02-14 20:35:34

回答

85

这是非常基本的

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

awk使用//搜索pattern,然后打印出的线,它默认称为记录,通过$ 0到4表示。至少读了documentation

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

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

由于'print'是默认动作:'awk'/ pattern /'file'就足够了。 – Johnsyweb 2011-04-04 08:22:59

+13

@Johnsyweb,是的,我知道这个事实。对于像marverix这样的初学者来说,它意味着更具视觉冲击力。 – kurumi 2011-04-04 08:25:37

+8

我不怀疑你的知识。然而,这些信息可能对其他人找到答案有用。 – Johnsyweb 2011-04-04 08:42:50

71

这听起来像你试图模仿GNU的grep -o行为。这将做到这一点提供你只需要在每一行的第一场比赛:

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

下面是一个例子:

% 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 

为了您的家庭作业的其余部分,你应该看看了每个什么matchsubstRSTARTRLENGTH做的awk手册。

之后,您可能希望扩大此处理在同一行上的多个匹配。我不能做全部你的功课:-)

+0

注意:要回答最后一部分,所有需要的构造都在[kurumi的答案](http://stackoverflow.com/questions/5536018/how-to-get-match-regex-pattern-using-awk-from -file/5536068#5536068)和我自己的。 – Johnsyweb 2011-04-04 10:04:17

+0

很棒的回答。只是因为我很懒,所以我想在这里解释一下。但这就是为什么我使用AWK! – 2014-08-22 22:08:14

+0

如果我想用匹配结果做一些事情,除了打印它呢?例如,我想将所有匹配添加到数组中。 – Evya2005 2017-06-04 09:41:46

8

如果你只对输入的最后一行感兴趣,而你期望只找到一个匹配(例如一个shell的摘要行的一部分)命令),你也可以尝试这种非常紧凑的代码,从Print regexp matches in AWK通过:

$ 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 

警告:awkmatch()函数三个参数只存在于gawk,而不是在mawk

下面是一个使用在grep,而不是awklookbehind regex另一个很好的解决方案。该解决方案具有较低的要求安装:

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

呆子可以用得到的每一行相匹配的部分以此为行动:

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

匹配(字符串,正则表达式[, array]) 如果存在数组,则将其清零, 然后将数组的第零个元素设置为由正则表达式匹配的 字符串的整个部分。如果正则表达式包含圆括号,则数组的整数索引元素 设置为包含与相应的括号化子表达式匹配的 字符串的部分。 http://www.gnu.org/software/gawk/manual/gawk.html#String-Functions

8

如果Perl是一种选择,你可以试试这个:

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