4

我在 linux 中有一个文本文件(基本上是一个日志文件),我有 2 个单词(alpha,beta)。

现在我尝试在一行中搜索这两个单词,然后在临时文件中打印该行和接下来的 15 行。会有很多行带有 alpha 和 beta 但我只需要最后一次出现“alpha”和“beta”以及接下来的 15 行。

如果您还告诉我命令以防单词数量增加,例如在同一行上搜索 3 或 4 个单词,alpha,beta,gamma,我将不胜感激

4

6 回答 6

5

您的措辞有点模棱两可,您是否想要一条同时包含 alpha AND beta 或 alpha OR beta 的行。如果是第一个:

grep -EA15 'alpha.*beta|beta.*alpha' | tail -16

如果是第二个:

grep -wA15 'alpha|beta' | tail -16
于 2012-04-23T20:51:34.407 回答
1

只要您坚持每行 2 个单词,OmnipotentEntity 绝对是最佳选择。然而,由于正则表达式中的组合爆炸,它并没有真正超出这个范围。如果您需要在一行中匹配 4 或 5 个单词,我认为类似下面的内容无需调整即可工作(我只对此进行了部分测试):


#!/bin/bash 

context=15
file=$1
shift

cmd="cat -n $file"
for s in $@
do
   cmd="$cmd | grep $s"
done

begin=$(eval $cmd | tail -1 | cut -f1)
(( end=$begin + $context ))

sed -n $begin,${end}p $file

这个想法是我们将行号附加到输入文件,然后构建一系列 grep 过滤器。我们提取通过所有过滤器的最后一行的行号,并使用 sed 打印出所需的范围。

于 2012-04-23T22:09:40.833 回答
1

这可能对您有用(GNU sed):

sed '/alpha.*beta\|beta.*alpha/,+15{//{h;d};H};$!d;g;/^$/d' file

或者这个(所有 sed 的):

sed '/alpha.*beta\|beta.*alpha/{:a;$bb;N;s/\n/&/15;tb;ba;:b;$q;x};$!d;g;/^$/d' file

使用两个词,正则表达式/alpha.*beta\|beta.*alpha/是可以接受的,但是从那里开始记住所有不同的组合变得更加棘手。如果该行不包含当前的正则表达式,更好的方法是在任何时候将单词列为单独的正则表达式:

sed '/alpha/!bc;/beta/!bc;/gamma/!bc;/delta/!bc;:a;$bb;N;s/\n/&/15;tb;ba;:b;$q;x;d;:c;$!d;g;/^$/d' file
于 2012-04-23T22:39:40.970 回答
0

请参阅以下代码:

awk '
    {
        file[NR]=$0
    }
    END{
        for (i=NR; i>0; i--) {
            if (file[i] ~ /^alpha, beta/)  {
                for (j=i; j<=i+15; j++) {
                    print file[j]
                }
                exit
            }
        }
    }
' FILE

算法是:

  • 对于文件的每一行,我们以当前行号作为键输入和数组
  • 在文件末尾,我们以相反的顺序搜索“alpha, beta”的第一次出现
  • 当行匹配时,我们打印它并按 ASC 顺序打印每个值,而数组键可以递增 15 次
于 2012-04-23T21:14:18.267 回答
0

您也可以使用 sed:

sed -n '/alpha.*beta|beta.*alpha/,+15p' file | tail -n 16
于 2012-04-23T22:25:19.097 回答
-2

获取特定单词的最后一次出现:“tail”

grep myword myfile.txt| tail -1

对于多个单词,

grep -w 'word1|word2' myfile.txt| tail -1

对于任一单词的最后 15 个实例,

grep -w 'word1|word2' myfile.txt| tail -15

对于更复杂的场景:“sed”或“awk”。

于 2012-04-23T20:50:54.510 回答