grep或sed只能显示符合一行中多个搜索模式的单词吗?

时间:2017-06-01 20:30:55

标签: perl awk sed grep

我想知道,如果可以在每一行中打印匹配的字符串...使用grep或sed?

TestCase1:File1包含以下文本

The Sun
Thunder The Rain They say
They say The dance

如果我使用此命令:

egrep -o 'The|They' File1

我得到的输出是:

The
The
They
They
The

但是,我的预期输出应该如下:

The
The They
They The

我知道,在grep中,选项-o, - only-matching只打印匹配行的匹配的非空部分,每个部分都在一个单独的输出行上。

编辑:如果想要一个具有多个匹配字符串的精确单词匹配的过滤器,请同时建议

 i.e. <The> and <They> exact word match? Space separated words simply.

TestCase2:File2包含以下文本

The Sun
Thunder The Rain They say
They say The dance
They're dancing with them in the dorm
The sun is shining the east and they scream.

输出是:

The
The They
They the
the
The the they

如何处理?

5 个答案:

答案 0 :(得分:4)

使用FPAT的GNU awk:

$ awk -v FPAT='\\<[Tt]hey?\\>' '{$1=$1}1' file
The
The They
They The
They the
The the they

请注意,They出现They're时无法识别$ awk '{c=0; for (i=1;i<=NF;i++) if ($i ~ /^[Tt]hey?$/) printf "%s%s", (c++?OFS:""), $i; print ""}' file The The They They The the The the they 。如果这确实是一个问题,并且您想要寻找以空格分隔的完整字符串,那么这可能是您想要的:

$ cat file
The Sun
Thunder The Rain They say
They say The dance
They're dancing with them in the dorm
The sun is shining the east and they scream.

如果没有,请告诉我们。

以上针对OPs发布的样本输入的迭代运行:

post "/hook/foo/bar" do
puts request.env

if request.env['TOKEN'] === "secret_code"
  HTTParty.post("https://hook.com/hooks/catch/foo/bar/",
  {
    :body => @info.to_json,
    :headers => { 'Content-Type' => 'application/json', 'Accept' => 'application/json'}
  })

  [200, {}, "Success"]
else
  [400, {}, "Authorization Failed"]
end

答案 1 :(得分:3)

最好用Perl做:

~$ perl -nE 'say /They? /g' File1
The
The They
They The

编辑:添加新条件。正则表达式仍然匹配除小写the以外的所有内容。添加i标志会使匹配不区分大小写并匹配所有测试字符串。

$ perl -nE 'say /They? /ig' File1
The
The They
They The
the
The the they

这里有一点技巧:匹配也会在?之后拾取空格并将其打印在输出中。例如。输出的第一行是真的:&#34; The_ \ n&#34; - 在哪里&#34; _&#34; =空格字符。这可能是也可能是不可接受的。删除空格并重新组合字符串的一种方法是:

$ perl -nE 'say join " ", map {substr $_,0,-1} /They? /ig' File1

关于匹配完整单词的问题&lt;&gt;和&lt;他们&gt;,如你所说,? They?表示&#39; y&#39;是可选的。即匹配0或1次。因此,该模式正在考虑&#39;和&#39;他们&#39;作为完整的单词,一个或另一个,后跟一个空格。您可以将模式重写为:

$ perl -nE 'say /(?:They|The) /ig' File1

并产生相同的输出。

既然你正在考虑小写the,你可能会遇到更多边缘案例&#34;陷阱&#34;喜欢以&#34;&#34;结尾的单词。 &#34;厌恶&#34; &#34; tythe&#34;浮现在脑海中。

$ echo "I'm loathe to cringe and tythe socks" >> File1
$ perl -nE 'say /They? /ig' File1
The
The They
They The
the
The the they
the the  <--- not wanted!

然后,您可以添加\b测试以匹配字边界(如zdim&#39;答案):

$ perl -nE 'say /\bThey? /ig' File1
The
The They
They The
the
The the they
              <-- But you get this empty line where no match occurs

因此,为了进一步细化,您只能在行匹配时进行打印。像这样:

$ perl -nE 'say /\bThey? /ig if /\bThey? /i' File1
The
The They
They The
the
The the they

然后,我确定,你可以找到更多的边缘案例,这些案例会将其全部搞砸并强制进一步完善。

答案 2 :(得分:2)

事情没有完全明确,所以这里有几种可能性

  • 要抓住以The开头的所有字词,然后用中间的空格打印

    perl -wnE'say join " ", /\bThe\w*/g' file
    

    其中\b是单词边界,零宽度anchor\w是单词字符。使用\S(非空格字符)更加宽容。

  • 仅限TheThey可以使用

    perl -wnE'say join " ", /\bThey?\b/g' file
    

    其中y?使y可选。

要允许the在模式中使用[tT]而不是T,或在所有字符中使用/i

在评论中已经澄清了The|They之后的标点符号是不允许的,而t的标点符号是[tT]。然后我们需要按空格约束匹配,而不是字边界,并使用perl -wnE'say join " ", /\b([Tt]hey?)\s/g' file 提到

()

现在需要捕获括号\s,因为\b确实消耗了,而不像之前的root@192:~# vxmlvalidator http://demo.ulex.fr/vxml/index.vxml ------------------------------------------------------------------------------ . VALID: http://demo.ulex.fr/vxml/index.vxml TIME PROCESSING: 213697 PAGES PARSED: 1 (4.67952 p/s)

使用提供的输入打印所需的输出。

答案 3 :(得分:1)

$ awk -v p="They?" '$0~p{for(i=1;i<=NF;i++) if($i~p) printf "%s",$i OFS; print ""}' file The The They They The 救援!

resolve

答案 4 :(得分:1)

再试一次awk:

awk '{while(match($0,/The|They/)){string=substr($0,RSTART,RLENGTH);VAL=VAL?VAL OFS string:string;$0=substr($0,RSTART+RLENGTH+1);};print VAL;VAL=""}'   Input_file

NON-ONE系列解决方案也如下。

awk '{
        while(match($0,/The|They/)){
                                        string=substr($0,RSTART,RLENGTH);
                                        VAL=VAL?VAL OFS string:string;
                                        $0=substr($0,RSTART+RLENGTH+1);
                                   };
        print VAL;
        VAL=""
     }
    '   Input_file

很快就会添加解释。

相关问题