如何使用linux为特定列中的每个元素添加新数字

时间:2018-05-18 00:31:01

标签: linux bash ubuntu awk sed

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

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

有人知道怎么做吗?

2 个答案:

答案 0 :(得分:1)

仅查看第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行,您的输出将被破坏。根据您的样本数据看起来不太可能。

答案 1 :(得分:0)

只需使用以下命令:

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

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