获取linux中最后一次出现的单词的行
我有两个值“usb 1-3”和“地址20”。现在我试图搜索一个文本文件(基本上是一个日志文件),其中包含这两个单词 现在,该文件有许多行,其中包含以下文字:获取linux中最后一次出现的单词的行,linux,bash,grep,Linux,Bash,Grep,我有两个值“usb 1-3”和“地址20”。现在我试图搜索一个文本文件(基本上是一个日志文件),其中包含这两个单词 现在,该文件有许多行,其中包含以下文字: Apr 27 13:30:55 box2 kernel: usb 1-3: USB disconnect, address 20 and Apr 27 13:25:43 box2 kernel: usb 1-3: new high speed USB device using ehci_hcd and address 20 现在我的要求是
Apr 27 13:30:55 box2 kernel: usb 1-3: USB disconnect, address 20
and
Apr 27 13:25:43 box2 kernel: usb 1-3: new high speed USB device using ehci_hcd and address 20
现在我的要求是:我想得到这两个单词倒数第二个出现的那一行,然后是接下来的16行。比如,如果文件中有6个匹配项(这两个单词都有6行),那么我需要第5个匹配项和后面的16行。如果有10个引用,那么我需要第9个引用和接下来的16行
目前我正在使用
egrep -A 20 'usb 1-3:.*address 20' filename | tail -16 > output.
但它给了我最后一次机会。不是倒数第二。请注意,这行应该有两个字,并且顺序相同(先是usb 1-3,后是地址20)
如果我的问题不清楚,请告诉我。提前感谢。这需要两次传球,但应该可以做到:
tail -n +`egrep -n 'usb 1-3:.*address 20' filename |
tac | sed -n '2s/:.*//p'` filename | head -17
您可以使用
awk
或perl
一次性完成,但需要管理一些缓冲区。请注意,它使用了tac
,这是一种反向cat
。如果您的系统上没有它,请尝试将tail-r
放到它的位置。使用perl
的单向操作:
use warnings;
use strict;
die qq[Usage: perl $0 <input-file>\n] unless @ARGV == 1;
my (@lines, $found);
## Reverse content and pipe output to perl.
open my $fh, q[-|], qq{tac $ARGV[0]} or die qq[Open error: $!\n];
## Read line by line.
while ( <$fh> ) {
## Remove trailing '\n'.
chomp;
## Use an array as a FIFO structure and save last 16 lines
## processed.
if ( @lines > 16 ) {
pop @lines;
}
unshift @lines, $_;
## Count how many lines matches at same time 'usb 1-3' and
## 'address 20'.
if ( m/usb\s1-3/ && m/address\s20/ ) {
++$found;
}
## In second one, print lines saved.
if ( ($found || 0) == 2 ) {
printf qq[%s\n], join qq[\n], @lines;
}
}
使用警告;
严格使用;
除非@ARGV==1,否则死掉qq[用法:perl$0\n];
我的(@lines,$find);
##将内容和管道输出反转为perl。
打开我的$fh,q[-|],qq{tac$ARGV[0]}或死亡qq[打开错误:$!\n];
##逐行阅读。
而{
##删除尾部“\n”。
咀嚼;
##使用数组作为FIFO结构并保存最后16行
##已处理。
如果(@lines>16){
弹出@行;
}
取消移动@行,$\;
##计算同时与“usb 1-3”匹配的行数,并
##“地址20”。
如果(m/usb\s1-3/&&m/address\s20/){
++$found;
}
##在第二种情况下,打印行已保存。
如果($found | | 0)==2){
printf qq[%s\n],加入qq[\n],@lines;
}
}
如果您有GNU grep
grep -B 1 -A 15 'usb 1-3.*address 20' filename
很抱歉,它不能正常工作。给出一些混合类型的线条。不是我需要的。。。在我的需求日志文件中,显示了时间“13:25:43”的行,但在您给定的语法中,我得到了一些行13:16:29,然后是一些行。13:12:22我看不到您的输入。但让我解释一下它是如何工作的。它只找到所有匹配的行(
egrep
),获取倒数第二个匹配的行号(tac
,sed
),从该行号开始跟踪整个文件(tail
),并吐出这些行中的前17行(head
)。也许你可以用你的数据来尝试这些步骤,看看哪里出了问题。首先检查grep。好的,我知道你哪里做错了。你的第一部分是完美的获得行号。但在那之后,当你试图跟踪的时候,那就错了。例如就我而言,是119号线。现在,当我输入“tail-119 filename”时,它给出了最后119行。这里它出错了。相反,它应该跳过前118行,然后给出接下来的17行(包括那一行)啊,是的。谢谢。那应该是从第1234行开始的tail-n+1234
。谢谢调试。我已经用这三个缺少的字符更新了答案!这如何识别模式的倒数第二次出现?我看到这里发生了什么。这是“用户未知”问题第二版的最佳选项“但它根本没有解决最初的问题。“用户未知”我认为你已经实质性地改变并误解了这个问题。我试图在不改变内容的情况下澄清这个问题。谢谢大家的努力。