从尾巴命令中掠过两个不同的东西

时间:2016-05-28 00:29:47

标签: perl grep tail

有没有办法用perl(perl是必须的)在单个cmd行中grep 2个单词的实例或1个另一个单词的实例

我正在尝试做一个tail -f文件| grep -m 2 word_x或grep word_y

我试图在文件中捕获word_x两次,如果发生这种情况,那么尾部会停止。 但是word_x并不总是出现,所以我想要另一个word_y来停止tail命令。

如果word_x出现2次或更多次中止尾部;
如果word_x只出现一次,则查找word_y的一个ocurrance并中止尾部;
如果word_x没有出现但字y出现在尾部中止;

Word_y是我的文件中始终显示的最后一个单词。

所以它可以像这3个例子

文本
文字
word_x 文本 word_x
测试
word_y

文本
文字
文本 word_x
测试
word_y

文本
文字
文字
word_y

我需要拖尾文件。我可以使用其他命令,它不需要是grep。

这可能吗?我已经尝试过几个但是不能提供一个简单的解决方案,也许它不可能在单个命令行指令上完成。

2 个答案:

答案 0 :(得分:0)

没有样本输入/输出,这是一个猜测但是这样的声音是你正在寻找的:

tail file | awk '{x+=gsub(/word_x/,"&")} x==2||/word_y/{exit} 1'

根据您尚未与我们分享的要求,您可能也需要字词边界,例如用GNU awk:

tail file | awk '{x+=gsub(/\<word_x\>/,"&")} x==2||/\<word_y\>/{exit} 1'

如果您只想考虑word_x在一行上出现两次的案例那么它就更简洁了:

tail file | awk 'gsub(/\<word_x\>/,"&")==2||/\<word_y\>/{exit} 1'

答案 1 :(得分:0)

  

(1)如果word_x出现2次或更多次中止尾部

很清楚。但是,以下是不一致的

  

(2)如果word_x只出现1次,请查找word_y

这表示只有在word_y

一行出现时才查找word_x
  

(3)并且如果word_x没有出现而中止尾部但是y出现中止尾部

但是,如果word_y ,则仅显示word_x

(2)和(3)似乎有冲突。对我来说,忽略(2)和使用(3)是最有意义的。

另外,你没有说你是否想要&#34; abort&#34;要传递的线路。

这里有一些我认为可行的代码。我做了一些最小的测试

#!/usr/bin/perl

my($word_x) = shift(@ARGV);
my($word_y) = shift(@ARGV);

# quirk of perl -- the regex needs the longest to be first in order if had
# similar words like "abc" and "abcd"
my(@rgx) = ($word_x,$word_y);
@rgx = sort({length($b) <=> length($a)} @rgx);
my($rgx) = join("|",@rgx);

while (my $buf = <STDIN>) {
    chomp($buf);

    # NOTE: this assumes the "abort" line should be printed
    print($buf,"\n");

    # get frequency of each word
    # NOTE: this grabs partials, so it may need \b or \W wrappers
    my(%freq);
    while ($buf =~ /($rgx)/go) {
        $freq{$1} += 1;
    }

    my $xcnt = $freq{$word_x};

    # got two or more of x -- we're done
    last if ($xcnt >= 2);

    # only look for y if x does _not_ appear at all
    if ($xcnt == 0) {
        # found a y -- we're done
        last if ($freq{$word_y} >= 1);
    }

    # NOTE: this assumes the "abort" line should _not_ be printed
    # use either of the prints but _not_ both
    ###print($buf,"\n");
}