查找唯一的行,忽略某些列

查找唯一的行,忽略某些列

我希望能够浏览文件并找到我期望稳定的字段中不同的行,忽略我知道会有所不同的字段中的差异。

我想忽略第 2、5、6 列 - 第 1、3、4 列中的更改值得报告。

举个例子:

在此输入图像描述

我不希望前两行被报告为包含更改,但我希望报告第二对到两行。

该文件已经排序

sort -k1,1 -k3,3n -k4,4n

有什么建议么? (对问题格式表示歉意,我是新人)

非图像形式的数据,前后添加行:

NZ_CP020102     B4U62_RS00130   26852   28543   DNA polymerase III subunit gamma/tau    NCIB3610a
NZ_CP020102     TESTGENOMECL_26 26852   28543   DNA polymerase III subunit gamma/tau    TESTGENOME
NZ_CP020102     B4U62_RS00135   28567   28890   YbaB/EbfC family nucleoid-associated protein    NCIB3610a
NZ_CP020102     TESTGENOMECL_27 28567   28890   YbaB/EbfC family nucleoid-associated protein    TESTGENOME
NZ_CP020102     B4U62_RS00140   28905   29501   recombination protein RecR      NCIB3610a
NZ_CP020102     TESTGENOMECL_28 28905   29501   recombination protein RecR      TESTGENOME
NZ_CP020102     B4U62_RS00145   29519   29743   DUF2508 domain-containing protein       NCIB3610a
NZ_CP020102     TESTGENOMECL_29 29519   29743   DUF2508 domain-containing protein       TESTGENOME
NZ_CP020102     B4U62_RS00150   29810   30073   sigma-K factor-processing regulatory protein BofA       NCIB3610a
NZ_CP020102     TESTGENOMECL_30 29810   30073   sigma-K factor-processing regulatory protein BofA       TESTGENOME
NZ_CP020102     B4U62_RS00155   30317   31869   16S ribosomal RNA       NCIB3610a
NZ_CP020102     TESTGENOMECL_31 30317   31870   16S ribosomal RNA       TESTGENOME
NZ_CP020102     B4U62_RS00160   31969   32045   tRNA-Ile        NCIB3610a
NZ_CP020102     TESTGENOMECL_32 31969   32045   tRNA-Ile        TESTGENOME

由于第 4 列中的差异,唯一应返回的相关不同的两行是两条 16s 行。

大多数情况下,线路是成对的,但也可能有遗漏

NZ_CP020102     B4U62_RS00085   20006   20596   pyridoxal 5'-phosphate synthase glutaminase subunit PdxT        NCIB3610a
NZ_CP020102     TESTGENOMECL_17 20006   20596   pyridoxal 5'-phosphate synthase glutaminase subunit PdxT        TESTGENOME
NZ_CP020102     TESTGENOMECL_4554       20704   20925   hypothetical protein    TESTGENOME
NZ_CP020102     B4U62_RS00090   20918   22195   serine--tRNA ligase     NCIB3610a
NZ_CP020102     TESTGENOMECL_18 20918   22195   serine--tRNA ligase     TESTGENOME

在这种情况下,我感兴趣的是未配对的线。

本质上,我希望抑制列,运行差异,但然后让差异输出包含抑制的列。

答案1

前提:这更多的是一个概念证明,而不是一个真正的解决方案,将自己定位在不优雅和完全丑陋之间。

我不太清楚您的要求,所以这是我的假设:

  • 您想要挑选出所有且仅具有其列子集(1、3 和 4)的唯一组合的行。如果您对不同的东西感兴趣 - 例如,仅对几行(不多不少于两行)感兴趣,两列的值相同,第三列的值不同 - 请更新您的问题以使其清楚。
  • 您想要打印出所选行(所有六列)的全部内容。
  • 行中的字段以制表符分隔 - 而不是空格分隔。 (否则会有点奇怪,因为你的第五列似乎包含空白字符)。该方法必须适应不同的字段分隔符。

在此代码中(将两次出现的 替换your_file为实际文件名):

grep -f \
<(sort -k 1b,1b -k 3n,3n -k 4n,4n your_file |
  nl -n rz -w 9 |
  cut -f 1,2,4,5 |
  uniq -f 1 -c |
  grep '^[[:space:]]*1' |
  sed 's/\(^[[:space:]]*1[[:space:]]*\)\(.*\)/^\2/' |
  cut -f 1) \
<(sort -k 1b,1b -k 3n,3n -k 4n,4n your_file |
  nl -n rz -w 9) |
  sed 's/\(^[0-9]\+[[:space:]]*\)\(.*\)/\2/'
  • 您的文件按第 1、3 和 4 列排序(可能没有必要,因为您在问题中说过您已经这样做了)。
  • 已排序的行已编号:固定 9 个字符长度的前导数字,以零填充。
  • cut仅提取您有兴趣比较的树字段,加上第一个字段(行号)。
  • uniq对每个结果行的重复项进行计数,忽略第一个字段(行号),并将计数添加到每行的开头。
  • grep仅选择计数等于 1 的行。
  • sed从每个结果行的开头删除计数。
  • cut仅提取第一个字段,即行号(这种方式比避免 previoussed和 attempts更容易cut -f 2)。
  • grep使用生成的行号集来过滤初始的编号行集。
  • 最终sed从过滤的行集中删除前导行号。

使用问题中的 14 行作为输入,它给出:

NZ_CP020102     B4U62_RS00155   30317   31869   16S ribosomal RNA       NCIB3610a
NZ_CP020102     TESTGENOMECL_31 30317   31870   16S ribosomal RNA       TESTGENOME

注意:您可能需要在运行此代码之前
使用export LC_ALL=C避免排序时出现问题一些字符。使用GNU 工具
在 Linux 上进行了测试。bash

相关内容