如何为目录中每个文件唯一的每个标头添加数字?

时间:2018-12-15 12:15:17

标签: bash awk bioinformatics

我有一个包含数百个多FASTA文件的目录。

在每个文件头中都遵循相同的命名逻辑,例如:

logo

其中:

>Bubo_bubo_c5_g1_i1 len=168 path=[174:0-148 24:148-168]是每个标题的开头

>是种类名称(与FASTA文件的名称相同,此处为Bubo_bubo

Bubo_bubo.fasta是序列的规范,所有其他字符是有关特定序列的其他信息

我想要做的是在特定文件的每个标头中,在种类名称和有关此文件的其他信息之间添加相同的编号,以获取诸如此类的信息:

c5_g1_i1

我希望每个文件的编号都不同。你能帮我吗?

2 个答案:

答案 0 :(得分:1)

这有点冗长,但我认为它可以完成工作:

awk 'BEGIN{FS="_"}filename!=FILENAME{++uniquenumber;filename=FILENAME}/^>/{printf "%s_%s_%03d_%s_%s_%s\n", $1,$2,uniquenumber,$3,$4,$5 > FILENAME"_updated";next}{print $0 > FILENAME"_updated"}' *

那将:

  1. 在处理(BEGIN{})之前,将字段分隔符设置为下划线。
  2. 如果变量filename不等于我们正在处理的文件FILENAME,则将uniquenumber变量加1,并将filename变量设置为当前文件名我们是FILENAME
  3. 如果行以>/^>/)开头
  4. 然后打印出一行,并使用前导0将唯一数字填充到三个字符上:(printf "%s_%s_%03d_%s_%s_%s\n", $1,$2,uniquenumber,$3,$4,$5
  5. 重定向输出相同的文件名,但后缀为_updated(您现在将拥有一个包含更改的新文件。并继续到文件中的下一行(> FILENAME"_updated";next
  6. 如果您仍然在这里,我们将保持正常状态。只需将其打印到相同的_updated文件中即可:{print $0 > FILENAME"_updated"}
  7. 对此目录*中的所有文件执行此操作

示例:

~/fasta$ ls
file1  file2  file3
~/fasta$ cat *
>Bubo_bubo_c5_g1_i1 len=168 path=[174:0-148 24:148-168]
blah
blah
>Bubo_bubo_c5_g1_i1 len=168 path=[174:0-148 24:148-168]
blah
>Bubo_bubo_c5_g1_i1 len=168 path=[174:0-148 24:148-168]
foo
bar
foo
>Bubo_bubo_c5_g1_i1 len=168 path=[174:0-148 24:148-168]
foo
>Bubo_bubo_c5_g1_i1 len=168 path=[174:0-148 24:148-168]

_bubo_c5_g1_i1 len=168 path=[174:0-148 24:148-168]
whatevfs
>Bubo_bubo_c5_g1_i1 len=168 path=[174:0-148 24:148-168]
asd
>Bubo_bubo_c5_g1_i1 len=168 path=[174:0-148 24:148-168]
~/fasta$ awk 'BEGIN{FS="_"}filename!=FILENAME{++uniquenumber;filename=FILENAME}/^>/{printf "%s_%s_%03d_%s_%s_%s\n", $1,$2,uniquenumber,$3,$4,$5 > FILENAME"_updated";next}{print $0 > FILENAME"_updated"}' file*
~/fasta$ cat *updated
>Bubo_bubo_001_c5_g1_i1 len=168 path=[174:0-148 24:148-168]
blah
blah
>Bubo_bubo_001_c5_g1_i1 len=168 path=[174:0-148 24:148-168]
blah
>Bubo_bubo_002_c5_g1_i1 len=168 path=[174:0-148 24:148-168]
foo
bar
foo
>Bubo_bubo_002_c5_g1_i1 len=168 path=[174:0-148 24:148-168]
foo
>Bubo_bubo_002_c5_g1_i1 len=168 path=[174:0-148 24:148-168]

_bubo_c5_g1_i1 len=168 path=[174:0-148 24:148-168]
whatevfs
>Bubo_bubo_003_c5_g1_i1 len=168 path=[174:0-148 24:148-168]
asd
>Bubo_bubo_003_c5_g1_i1 len=168 path=[174:0-148 24:148-168]

答案 1 :(得分:1)

这是使用Perl的一种方式

输入文件

$ ls -1 Bubo_bubo*fasta
Bubo_bubo.fasta
Bubo_bubo2.fasta
Bubo_bubo3.fasta
Bubo_bubo4.fasta

$ cat Bubo_bubo.fasta
>Bubo_bubo_c5_g1_i1 len=168 path=[174:0-148 24:148-168]
a b c

$ cat Bubo_bubo2.fasta
>Bubo_bubo_c5_g1_i1 len=168 path=[174:0-148 24:148-168]
d e f

$ cat Bubo_bubo3.fasta
>Bubo_bubo3_chihoig len=134 path=[174:0-148 24:148-168]
g h i

$ cat Bubo_bubo4.fasta
>Bubo_bubo4_wrwklk_gjf len-133 path=[174:0-148 24:148-168]
p q r

解决方案:

Perl -i就地替换所有文件。

$ perl -i.bak -pe ' if($.==1) { $y=sprintf("%03d",++$x); s/^>((.+?)_(.+?))_/>\1_${y}_/ } close(ARGV) if eof ' Bubo_bubo*fasta

输出:

$ cat Bubo_bubo.fasta
>Bubo_bubo_001_c5_g1_i1 len=168 path=[174:0-148 24:148-168]
a b c

$ cat Bubo_bubo2.fasta
>Bubo_bubo_002_c5_g1_i1 len=168 path=[174:0-148 24:148-168]
d e f

$ cat Bubo_bubo3.fasta
>Bubo_bubo3_003_chihoig len=134 path=[174:0-148 24:148-168]
g h i

$ cat Bubo_bubo4.fasta
>Bubo_bubo4_004_wrwklk_gjf len-133 path=[174:0-148 24:148-168]
p q r