【问题标题】:match columns in 2 tab-delimited text files匹配 2 个制表符分隔的文本文件中的列
【发布时间】:2017-03-30 09:47:54
【问题描述】:

我有两个制表符分隔的 .txt 文件

file1 有 2000 万行,结构如下

col1    col2    col3    col4    col5
1       x       x       A       x
2       y       y       A       x
3       z       z       A       x
4       x       x       B       x
5       x       y       B       x
6       x       y       E       x
7       x       z       F       x

file2 有 3000 行,结构如下

col1
A
B
C
D

现在我想从 file1 中提取 file2 的 col1 和 file1 的 col4 匹配的行

所以新的 file3 应该是这样的

col1    col2    col3    col4    col5
1       x       x       A       x
2       y       y       A       x
3       z       z       A       x
4       x       x       B       x
5       x       y       B       x

如何使用 perl 或 bash 做到这一点?

【问题讨论】:

    标签: bash perl


    【解决方案1】:

    您可以使用标准的 awk 命令来加入 2 个文件:

    awk 'BEGIN{FS=OFS="\t"} FNR == NR { a[$1]; next } $4 in a' file2 file1
    

    【讨论】:

      【解决方案2】:

      试试这个 -

      awk -F'[ ]+' 'NR==FNR {a[$1]++;next} $4 in a{print $0}' f2 f1
      1       x       x       A       x
      2       y       y       A       x
      3       z       z       A       x
      4       x       x       B       x
      5       x       y       B       x
      

      【讨论】:

        【解决方案3】:

        由于您还询问了 Perl,这里有一个可重用的 perl 解决方案。您首先读取文件 2,生成查找值数组,然后读取文件 1,打印出第 4 列与我们在上面创建的数组中的值匹配的任何行。这样的事情可能会奏效:

        #!/usr/bin/perl
        use strict;
        use warnings;
        use autodie;
        
        my $key_file = shift;
        open(my $fh, "<", $key_file);
        my $header = <$fh>; # read the header line into '$h'
        my %keys = map{ chomp; $_ => 1 }<$fh>;
        close $fh;
        
        my $query_file = shift;
        open(my $q_fh, "<", $query_file);
        print scalar <$q_fh>;
        while (<$q_fh>) {
            my @fields = split;
            print if $keys{$fields[3]};
        }
        close $q_fh;
        

        您可以将其运行为table_combine.pl &lt;file2&gt; &lt;file1&gt;

        【讨论】:

        • 最好使用哈希:my %keys = map { chomp; $_ =&gt; 1 } &lt;$fh&gt;,因为这样你就可以使用print if $keys{$fields[3]}。此外,您可以在第二个 open 之后使用 print scalar &lt;$fh&gt; 打印标题。这样就无需使用正则表达式检查该行。
        • 非常好的想法,谢谢!已根据您的建议进行了编辑。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-11-24
        • 2018-08-05
        • 2017-08-04
        • 2012-10-06
        • 1970-01-01
        • 2012-04-26
        • 1970-01-01
        相关资源
        最近更新 更多