【问题标题】:Print only '+' or '-' if string matches (two files)如果字符串匹配(两个文件),则仅打印 '+' 或 '-'
【发布时间】:2014-03-30 16:21:39
【问题描述】:

如果找到字符串,我只想打印一个 '+' o '-' 符号。基本上,我有两个文件:

输入文件 1(制表符分隔):

HPNK_00457
HPNK_00458
HPNK_00459

输入文件 2(制表符分隔):

HPNK_00457  AAA50325    1e-43   437 28  43  83  ATP-binding protein.
HPNK_00458  P25256  8e-43   429 28  43  82  RecName: Full=Tylosin resistance ATP-binding protein tlrC.
HPNK_00458  CAM96590    1e-42   429 27  42  87  ABC transporter ATP-binding protein [Streptomyces ambofaciens].

所需的输出(制表符分隔,保持文件 1 中字符串的顺序):

HPNK_00457 +
HPNK_00458 +
HPNK_00459 -

这是我一直在使用的,但需要更新:

while read vl; do grep "^$vl      " file2 || printf -- "- -\n" ; done < file1

谢谢,每天都在这里学习。

【问题讨论】:

    标签: regex perl parsing awk


    【解决方案1】:

    这是使用awk的一种方式:

    awk 'FNR==NR { a[$1]; next } { print $1, ($1 in a ? "+" : "-" ) }' file2 file1 
    

    结果:

    HPNK_00457 +
    HPNK_00458 +
    HPNK_00459 -
    

    【讨论】:

      【解决方案2】:

      你可以使用:

      while read -r line
      do
          grep -q "$line" f2 && echo "$line +" || echo "$line -"
      done < f1
      

      grep -q 仅在匹配某些内容时返回 true,在这种情况下,我们打印文件名 + + 否则,我们打印文件名 + -

      返回:

      $ while read -r line; do grep -q "$line" f2 && echo "$line +" || echo "$line -"; done < f1
      HPNK_00457 +
      HPNK_00458 +
      HPNK_00459 -
      

      【讨论】:

      • 啊!你不需要回报。这似乎是一个明显的疏忽,所以忍不住编辑。
      【解决方案3】:
      perl -lane'
        BEGIN{ $, ="\t"; $x=shift; @h{ map /(\S+)/, <> } =(); @ARGV=$x }
        print @F, exists $h{$F[0]} ? "+" : "-";
      ' file1 file2
      

      输出

      HPNK_00457      +
      HPNK_00458      +
      HPNK_00459      -
      

      【讨论】:

      • @h{ map /(\S+)/, &lt;&gt; } =() 的语法起初看起来令人困惑,但现在我明白了,它是一个哈希切片。 %h = map{ $_-&gt;[0]++ } map[split] , &lt;&gt;@h{ map { /(\S+)/ } &lt;&gt; }++ 也可以。再次感谢!
      • @JS웃 是的,它是一个哈希片。顺便说一句,@h{..}++ 只会增加键的最后一个值。 eval.in/133988
      • 好点@mpapec。我不是从那个角度看的。我猜它起作用了,因为在这种情况下,解决方案只需要哈希中存在密钥。感谢您在解释细节方面的帮助。
      【解决方案4】:

      算法如下:

      1. 读取文件 2。对于每一行,
      2. 得到第一个字
      3. 将其存储在哈希中。
      4. 读取文件 1。对于每一行,将其切碎,然后
      5. 打印$hash{$_}? '+' : '-'

      我可以为您编写代码,但如果您想每天学习,如果您想自己编写代码,这将是一个有用的练习。

      【讨论】:

        【解决方案5】:

        这个简单的 Perl 脚本应该可以完成这项工作

        #!/usr/local/bin/perl
        ## f1 and f2 are the 2 files containing your input data
        open FILE1, f1;
        open FILE2, f2;
        
        @file1data = <FILE1>;
        @file2data = <FILE2>;
        
        my $row = 0;
        foreach $data (@file1data) {
                chomp($data);
                if (grep (/$data/,$file2data[$row]) ) {
                        print $data . " " . "+\n";
                }
                else {
                        print $data . " " . "-\n";
                }
                $row++;
        }
        

        【讨论】:

        • 对我来说,他似乎想检查 file1 中的行是否存在于 file2 中。如果存在,则打印“+”或打印“-”。到目前为止,我的代码验证了 file1 中的行是否与 file2 中完全相同的行号匹配(这就是我在问题中解释了“维护文件 1 中字符串的顺序”这一​​行).. 如果要求是file1 中的行可以在 file2 的任何位置有相应的条目,我们可以轻松地将 grep 代码替换为您的哈希建议。截至目前,我认为如果我使用哈希,我不能保证维持秩序。
        【解决方案6】:
        awk 'FNR==NR
             {a[$1];next}
             {b[$1]}
             END{
             for(i in a)
             if(b[i]){print i,"+"}
             else{print i,"-"}
             }' file1 file2
        

        【讨论】:

        • 你认为 OP 会understand 这个基于awk 的答案吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-08-28
        • 1970-01-01
        • 2019-03-24
        • 2019-12-26
        • 2021-10-25
        • 2021-05-29
        • 1970-01-01
        相关资源
        最近更新 更多