在列上使用 bash comm 命令但返回整行

问题描述 投票:0回答:2

我有两个文件,每个文件有两列,仅按第二列排序,例如:

File 1: 

176 AAATC
6   CCGTG
80  TTTCG

File 2:

20 AAATC
77 CTTTT
50 TTTTT

我想使用带有选项 -13 和 -23 的 comm 命令来获取两个不同的文件,报告两个文件之间的不同行以及相应的计数,但仅比较第二列(即字符串)。到目前为止我尝试过的是:

comm -23 <(cut -d$'\t' -f2 file1.txt) <(cut -d$'\t' -f2 file2.txt)

但是我只能输出字符串,而没有数字:

 CCGTG
 TTTCG

虽然我想要的是:

 6  CCGTG
 80 TTTCG

有什么建议吗?

bash sorting command comm
2个回答
1
投票

您可以使用

join
代替
comm
:

join -1 2 -2 2 File1 File2 -a 1 -o 1.1,1.2,2.2

它也会输出匹配的行,但你可以用

删除它们
| grep -v '[ACTG] [ACTG]'

说明:

  • -1 2
    使用文件1中的第二列进行连接;
  • -2 2
    同样,使用文件2中的第二列;
  • -a 1
    还显示文件 1 中不匹配的行 - 这些是您最终想要的行;
  • -o
    指定输出格式,这里我们需要文件1中的第1列和第2列以及文件2中的第2列(这只是任意的,您也可以使用第1列,但第二个命令会有所不同:
    | grep -v '[ACTG] [0-9]'
    ).

0
投票

comm
不是适合这项工作的工具,虽然
join
可以工作,但您还需要查看运行
join
两次,然后使用其他命令(例如,
grep
)进一步过滤结果。

一个

awk
的想法需要单次遍历每个输入文件:

awk 'BEGIN {FS=OFS="\t"}

FNR==NR  { f1[$2]=$1; next }           # save 1st file entries

$2 in f1 { delete f1[$2]; next }       # 2nd file: if $2 in f1[] then delete f1[] entry and skip this line else ..
         { f2[$2]=$1 }                 # save 2nd file entries

END      { # at this point:
           # f1[] contains rows where field #2 only exists in the 1st file
           # f2[] contains rows where field #2 only exists in the 2nd file

           PROCINFO["sorted_in"]="@ind_str_asc"
           for (i in f1) print f1[i],i > "file-23"
           for (i in f2) print f2[i],i > "file-13"
         }
' file1 file2

注意:

PROCINFO["sorted_in"]
行需要
GNU awk
;如果没有这一行,我们无法保证最终输出文件的写入顺序,然后 OP 需要添加更多 (
awk
) 代码来维护顺序或使用另一个操作系统级实用程序(例如,
sort
)来排序最终文件

这会生成:

$ cat file-23
6       CCGTG
80      TTTCG

$ cat file-13
77      CTTTT
50      TTTTT
© www.soinside.com 2019 - 2024. All rights reserved.