【问题标题】:how to extract common lines across multiple file?如何跨多个文件提取公共行?
【发布时间】:2016-09-04 18:05:42
【问题描述】:

我有 15 个不同的文件,我想要一个新文件,其中只包含公共行。例如:

File1:

id1
id2
id3

file2:

id2
id3
id4

file3:
id10
id2
id3

file4

id100
id45
id3
id2

I need the output be like:

newfile:

id2 
id3

我知道这个命令适用于每对文件:

grep -w -f file1 file2 > 输出

但我需要一个命令来处理超过 2 个文件。

有什么建议吗?

【问题讨论】:

    标签: perl shell grep comm


    【解决方案1】:

    zet 命令提供输入文件之间的集合操作。使用intersect 选项获取所有输入文件的公共行。输入内容不必排序。输出顺序将与输入行的顺序相同。

    $ zet intersect file1 file2 file3 file4
    id2
    id3
    

    这里有一些相关细节from the notes section

    • 每个输出行只出现一次,因为我们将文件视为集合,将行视为元素。
    • Zet 将整个文件读入内存。它的内存使用量大致与其最大参数的文件大小加上(最终)输出的大小成正比。

    【讨论】:

      【解决方案2】:

      Perl 的救援:

      perl -lne 'BEGIN { $count = @ARGV }
                 $h{$_}{$ARGV} = 1;
                 }{
                 print $_ for grep $count == keys %{ $h{$_} }, keys %h
                 ' file* > newfile
      
      • -n逐行读取输入文件
      • -lprint 添加一个换行符
      • @ARGV 数组包含输入文件名,将其分配给 $countBEGINning 上只是计数它们
      • $ARGV 包含当前输入文件的名称
      • $_ 包含从文件中读取的当前行。
      • %h 散列包含 id 作为键,每个键都包含一个散列引用,其中文件名包含 id 作为键
      • }{ 是“Eskimo greeting”操作符,它引入了在输入用完后运行的代码
      • 我们只输出文件数等于所有文件数的id。它适用于任意数量的文件。

      【讨论】:

      • -l 不是也让chomp 变得多余吗?
      【解决方案3】:

      使用 grep

      同样的技巧可以多次使用:

      $ grep -w -f file1 file2 | grep -w -f file3 | grep -w -f file4
      id2
      id3
      

      顺便说一句,如果您正在寻找完全匹配,而不是 正则表达式 匹配,使用-F 标志会更好更快:

      $ grep -wFf file1 file2 | grep -wFf file3 | grep -wFf file4
      id2
      id3
      

      使用 awk

      $ awk 'FNR==1{nfiles++; delete fseen} !($0 in fseen){fseen[$0]++; seen[$0]++} END{for (key in seen) if (seen[key]==nfiles) print key}' file1 file2 file3 file4
      id3
      id2
      
      • FNR==1{nfiles++; delete fseen}

        每次我们开始读取一个新文件时,我们都会做两件事:(1) 增加文件计数器,nfiles。 (2) 删除数组fseen

      • !($0 in fseen){fseen[$0]; seen[$0]++}

        如果当前行不是fseen 中的键,则将其添加到fseen 并增加seen 中该行的计数。

      • END{for (key in seen) if (seen[key]==nfiles) print key}

        读完最后一个文件的最后一行后,我们查看seen 中的每个键。如果该键的计数等于我们已读取的文件数nfiles,则我们打印该键。

      【讨论】:

        【解决方案4】:
             grep -hxf file1 file2 file3 file4 |sort -u
             id2
             id3
        
             # For storing it to any file, 
             grep -hxf file1 file2 file3 file4 |sort -u > output.txt
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-07-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-01-29
          相关资源
          最近更新 更多