【问题标题】:How to add a number to every header, unique to each file in a directory?如何为每个标题添加一个数字,对于目录中的每个文件都是唯一的?
【发布时间】:2018-12-15 21:17:21
【问题描述】:

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

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

>Bubo_bubo_c5_g1_i1 len=168 path=[174:0-148 24:148-168]

在哪里:

> 是每个标头的开头

Bubo_bubo 是物种名称(与 FASTA 文件的名称相同,此处为:Bubo_bubo.fasta

c5_g1_i1 是一个序列的规范,所有其他字符都是关于特定序列的附加信息

我想要做的是在特定文件中的每个标题中添加相同的数字,在物种名称和有关该文件的其他信息之间,以获得类似:

>Bubo_bubo_001_c5_g1_i1 len=168 path=[174:0-148 24:148-168]

我希望每个文件的数字都不同。你能帮我解决一下吗?

【问题讨论】:

  • Bubo_bubo 对于不同的文件名会有所不同.. 对吧?
  • 是的@stack0114106,正确!
  • 我可以假设在第二个下划线之后,出现了特定的序列部分
  • 是的!是这样的

标签: bash awk bioinformatics


【解决方案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]

【讨论】:

  • 您的命令完美运行!另外,非常感谢您的精彩解释。我不知道我可以简单地在最后添加“*”来以相同的方式处理目录中的所有文件,而不是使用循环。我不得不承认 awk 语法对我来说非常棘手,但是有了这个解释我才真正开始理解它。
  • 如果您要对这些类型的文件进行操作,awk 绝对值得学习。我见过很多人来这里尝试修改 fasta 文件,awk 似乎总是能很好地完成这项工作。
  • 我一直在寻找某种关于基础知识的教程,但除了实际的手册外,并没有真正找到任何东西。你能推荐任何值得一看的教程吗?
【解决方案2】:

这是使用 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

【讨论】:

  • 谢谢@stack0114106!这是否意味着如果我在 fasta 文件中有多个标题,我应该在 s/^>((.+?)_(.+?))_/>\1_${y}_/ 的末尾添加 g 吗?
  • 这里不需要 g,因为我们已经在过滤第一行 ($.==1) 并且我们将表达式的开头锚定为 ^>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-15
  • 1970-01-01
相关资源
最近更新 更多