【问题标题】:How to add a new number to every element in a specific column, using linux如何使用linux为特定列中的每个元素添加一个新数字
【发布时间】:2018-10-28 08:33:38
【问题描述】:

我有一个像这样的巨大文本文件:

Chr1  11000   11500   geneA  0
Chr1  11500   12000   geneA  6
Chr1  12000   12500   geneA  0
Chr1  12500   13000   geneA  7
...
Chr30  120000   125000   geneZ  7
Chr30  125000   130000   geneZ  7

我需要对基因名称的每个实例进行单独编号(第 4 列)。例如,它将变为以下内容:

Chr1  11000   11500   geneA_1  0
Chr1  11500   12000   geneA_2  6
Chr1  12000   12500   geneA_3  0
Chr1  12500   13000   geneA_4  7
...
Chr30  12500   13000   geneZ_939  7
Chr30  12500   13000   geneZ_940  7

有人知道如何做到这一点吗?

【问题讨论】:

  • Stack Overflow 不是代码编写服务。请出示您的代码。由于 Stack Overflow 向您隐藏了关闭原因:寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定问题或错误以及在问题本身。没有明确问题陈述的问题对其他读者没有用处。请参阅:How to create a Minimal, Complete, and Verifiable example
  • @jww - 我想这就是为什么我的回答也被否决了? (如果是这样就足够公平了)
  • jww 在他留下评论时总是对所有答案投反对票,然后我和其他人都投赞成票以进行补偿。
  • @EdMorton stackoverflow 很奇怪 :)

标签: linux bash ubuntu awk sed


【解决方案1】:

只需使用以下命令:

awk 'BEGIN {i=1;} {print $1" "$2" "$3" "$4"_"i" "$5; i++;}' filename > tmpfile
mv tmpfile filename

根据您的文件或需要使用制表符而不是空格。

【讨论】:

    【解决方案2】:

    仅查看第 4 列的基本想法是您将列数据用作计数器的associative array/hash 的索引:

    awk '{i[$4]++; print $4 "_" i[$4]}' gene
    

    为了保留其他数据...:

    awk '{i[$4]++; c4 = $4 "_" i[$4]; gsub($4, c4);print;}' #and optionally >outFile 
    

    如果您一心想要就地覆盖文件,我认为标准 awk 不支持:

    perl -i~ -ape 'if (!($F[3] =~ /_\d+$/)) { $i{$F[3]}++; $c4 = "$F[3]_$i{$F[3]}"; s/$F[3]/\Q$c4/}' gene
    

    这会处理gene 并创建一个gene~ 备份文件。 perl 也不会处理同一个文件两次(如果它看到_ 和第 4 列末尾的数字,它会跳过该行)

    警告:如果您的基因名称存在于第 1-3 行,您的输出将被破坏。不过根据您的示例数据,这看起来不太可能。

    【讨论】:

    • 谢谢!无论如何我可以将它打印到当前的文本文件中吗?那样的话,新列已经在里面了?
    • @Steveman30290 - 我不建议使用 awk 覆盖您当前的文件。正常是重定向,然后将新文件 mv 覆盖在旧文件上。
    猜你喜欢
    • 2018-07-26
    • 1970-01-01
    • 1970-01-01
    • 2021-01-05
    • 2021-08-06
    • 2014-06-23
    • 2017-03-05
    • 2015-05-29
    • 1970-01-01
    相关资源
    最近更新 更多