比较两个文件并在匹配的单词后打印N行

时间:2015-02-08 13:59:31

标签: linux perl awk grep

我需要针对File1搜索File2的名称。如果找到了匹配的名称,我需要将它与三条线一起打印出来。

- File1 -

Name1
Name2
Name3

- File2 -

Topic1 ....description...
lineA
lineB
lineC
Name1 ....description...
lineA
lineB
lineC
Name3 ....description...
lineA
lineB
lineC
Topic2 ....description...
lineA
lineB
lineC
Topic3 ....description...
lineA
lineB
lineC

- 预期结果 -

Name1 ....description...
lineA
lineB
lineC
Name3 ....description...
lineA
lineB
lineC
  • 我尝试使用awk查找两个文件之间的匹配,但只能成功打印Name1 ....description...(没有lineA - lineC

    awk 'BEGIN { while ( getline < "File1" ) arr[$0]++ }( $1 in arr )' File2
    
  • 我知道grep命令可用于使用模式

    打印某些行
    grep -A3 /pattern/ file
    

我现在的问题是我不知道如何组合这两个命令。也许有人可以建议使用Perl脚本来运行这些流程?

3 个答案:

答案 0 :(得分:1)

您可以向grep传递包含模式(-f选项)的文件,所以

$ grep -F -f file1 -A3 file2
Name1 ....description...
lineA
lineB
lineC
Name3 ....description...
lineA
lineB
lineC

使用-F表示模式是固定字符串,而不是正则表达式。

答案 1 :(得分:1)

这对你有用。它将File1中的所有名称读入哈希值,以便快速检查File2中的值。

逐行读取

File2,并根据哈希检查第一个字段以查看它是否是所需名称之一。如果是,则打印当前行和以下三行。

use strict;
use warnings;
use 5.010;
use autodie;

my %names;

open my $fh, '<', 'File1';

while ( <$fh> ) {
  chomp;
  ++$names{$_};
}

open $fh, '<', 'File2';

while ( <$fh> ) {
  my ($name) = split;
  if ( $names{$name} ) {
    print;
    print scalar <$fh> for 1 .. 3;
  }
}

<强>输出

Name1 ....description...
lineA
lineB
lineC
Name3 ....description...
lineA
lineB
lineC

答案 2 :(得分:0)

我会使用xargs:

cat File1 | xargs -I NAME grep -A3 NAME File2

在File2中查找NAME并在其后显示匹配行和三行的规范方法:

grep -A3 NAME File2

使用行作为NAME为文件1的每一行生成此类命令的方法是:

cat File1 | xargs -I NAME <COMMAND with NAME in it>