【问题标题】:How do I line number a set of columns taking into account the strings values of the first column (UNIX shell)考虑到第一列的字符串值,我如何对一组列进行行号(UNIX shell)
【发布时间】:2019-02-03 06:08:05
【问题描述】:

有人可以帮助我吗?我想在 UNIX 中对列表文件进行编号取决于该文件中的列。但是,某些行的最后一列在它们之间具有相同的字母和长度,但顺序不同,如果其他先前的列也相同,则必须将其视为相同。总之,输入类似于

rs758613821  574290     insertion_inframe   P   285  AAAP
rs758613821  574290     insertion_inframe   P   285  APAA
rs758613821  574290     insertion_inframe   P   285  APLA
rs1367252071 574290     deletion_inframe    CADDL   134  F
rs538        3246       frameshift_variant  F   97  FGLYP
rs538        3246       frameshift_variant  F   97  PYFLG

输出应该是

1 rs758613821    574290     insertion_inframe   P   285  AAAP
1 rs758613821    574290     insertion_inframe   P   285  APAA
2 rs758613821    574290     insertion_inframe   P   285  APLA
3 rs1367252071   574290     deletion_inframe    CADDL   134  F
4 rs538          3246       frameshift_variant  F   97  FGLYP
4 rs538          3246       frameshift_variant  F   97  PYFLG

等等……

通过这种方式,我执行了如下代码

awk 'BEGIN {FS=OFS="\t"} function intern(sym) { if (sym in table)
                          return table[sym]
                        return table[sym] = ++counter }
 { print intern($1"\t"$2"\t"$3"\t"$4"\t"$5"\t"$6), $0 }' "input" > "output";

尽管如此,我没有解决关于最后一列分配相同数字的问题,如果字母和长度相同,尽管顺序不同。是否可以在 UNIX 环境中执行此操作?我想可能是通过 substr 函数或类似的方法,但我不确定什么是正确的代码。提前感谢您的支持和帮助!

【问题讨论】:

  • 非常感谢@gregory 的更正和重新编辑标题

标签: bash for-loop unix awk


【解决方案1】:

不确定这是您想要做的,但请尝试一下

$ awk 'function canon(f) {n=split(f,a,""); 
                          asort(a); c=""; 
                          for(i=1;i<=n;i++) c=c a[i]; 
                          return c;}
                         {key=canon($NF)} 
          !(key in keys) {keys[key]=++ctr} 
                         {print keys[key],$0}' file

1 rs758613821  574290     insertion_inframe   P   285  AAAP
1 rs758613821  574290     insertion_inframe   P   285  APAA
2 rs758613821  574290     insertion_inframe   P   285  APLA
3 rs1367252071 574290     deletion_inframe    CADDL   134  F
4 rs538        3246       frameshift_variant  F   97  FGLYP
4 rs538        3246       frameshift_variant  F   97  PYFLG

将最后一个字段转换为规范形式并计算唯一实例。

要使用完整记录作为键,请改为这样做

                 ...
                 {line=$0;
                  $NF=canon($NF);
                  key=$0} 
  !(key in keys) {keys[key]=++ctr} 
                 {print keys[key],line}' file

复制该行,用规范形式替换最后一个字段,使用更新的行作为键,计算唯一实例,打印计数和原始行

【讨论】:

  • 工作正常!非常感谢@karafka,但是我也需要考虑其他列。这样,如果第 2 行的第 3 列与前一行不同,则数字也必须不同,并且将变为数字 2 而不是数字 1
  • 是否有可能在代码中包含考虑它?不过再次感谢您的帮助!
  • 好的,我已经解决了。将 key=canon($NF) 替换为 key=canon($0) 足以考虑其他列。我理解了代码的大部分,但有些部分让我感到困惑。能不能肤浅地给我解释一下?
  • 不要那样做,它可能会给你错误的匹配。请参阅更新版本。让我知道哪一部分不清楚。
  • 是的,正确的。由于顺序对于最后一个字段字符并不重要,因此最简单的方法是对它们进行排序和比较。
猜你喜欢
  • 2018-08-01
  • 2021-02-19
  • 2011-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-01
  • 1970-01-01
相关资源
最近更新 更多