如何为目录中每个文件的每个 header 添加一个唯一的数字?
How to add a number to every header, unique to each file in a directory?
我有一个包含数百个 multi-FASTA 个文件的目录。
在每个文件header中遵循相同的命名逻辑,例如:
>Bubo_bubo_c5_g1_i1 len=168 path=[174:0-148 24:148-168]
其中:
>
是每个header
的开始
Bubo_bubo
为种名(与FASTA文件名相同,此处为Bubo_bubo.fasta
)
c5_g1_i1
是一个序列的规范,所有其他字符都是关于特定序列的附加信息
我想做的是在特定文件中,在物种名称和关于该文件的其他信息之间,为每个 header 添加相同的数字,以获得类似:
>Bubo_bubo_001_c5_g1_i1 len=168 path=[174:0-148 24:148-168]
我希望每个文件的编号都不同。你能帮我解决一下吗?
这有点冗长,但我认为它可以完成工作:
awk 'BEGIN{FS="_"}filename!=FILENAME{++uniquenumber;filename=FILENAME}/^>/{printf "%s_%s_%03d_%s_%s_%s\n", ,,uniquenumber,,, > FILENAME"_updated";next}{print [=10=] > FILENAME"_updated"}' *
那将:
- 在处理 (
BEGIN{}
) 之前将字段分隔符设置为下划线。
- 如果变量
filename
不等于我们正在处理的当前文件 FILENAME
然后将 uniquenumber
变量递增 1 并将 filename
变量设置为我们正在处理的当前文件名 FILENAME
- 如果该行以
>
(/^>/
) 开头
- 然后打印出使用前导 0 将唯一编号添加到三个字符的行:(
printf "%s_%s_%03d_%s_%s_%s\n", ,,uniquenumber,,,
)
- 重定向输出相同的文件名,但带有
_updated
后缀(您现在将拥有一个包含更改的新文件。并继续文件中的下一行 (> FILENAME"_updated";next
)
- 如果你还在这里,那我们就是常线了。只需将其打印到同一个
_updated
文件:{print [=24=] > FILENAME"_updated"}
- 对该目录中的所有文件执行此操作
*
示例:
~/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", ,,uniquenumber,,, > FILENAME"_updated";next}{print [=11=] > 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]
这是使用 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/^>((.+?)_(.+?))_/>_${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
我有一个包含数百个 multi-FASTA 个文件的目录。
在每个文件header中遵循相同的命名逻辑,例如:
>Bubo_bubo_c5_g1_i1 len=168 path=[174:0-148 24:148-168]
其中:
>
是每个header
Bubo_bubo
为种名(与FASTA文件名相同,此处为Bubo_bubo.fasta
)
c5_g1_i1
是一个序列的规范,所有其他字符都是关于特定序列的附加信息
我想做的是在特定文件中,在物种名称和关于该文件的其他信息之间,为每个 header 添加相同的数字,以获得类似:
>Bubo_bubo_001_c5_g1_i1 len=168 path=[174:0-148 24:148-168]
我希望每个文件的编号都不同。你能帮我解决一下吗?
这有点冗长,但我认为它可以完成工作:
awk 'BEGIN{FS="_"}filename!=FILENAME{++uniquenumber;filename=FILENAME}/^>/{printf "%s_%s_%03d_%s_%s_%s\n", ,,uniquenumber,,, > FILENAME"_updated";next}{print [=10=] > FILENAME"_updated"}' *
那将:
- 在处理 (
BEGIN{}
) 之前将字段分隔符设置为下划线。 - 如果变量
filename
不等于我们正在处理的当前文件FILENAME
然后将uniquenumber
变量递增 1 并将filename
变量设置为我们正在处理的当前文件名FILENAME
- 如果该行以
>
(/^>/
) 开头
- 然后打印出使用前导 0 将唯一编号添加到三个字符的行:(
printf "%s_%s_%03d_%s_%s_%s\n", ,,uniquenumber,,,
) - 重定向输出相同的文件名,但带有
_updated
后缀(您现在将拥有一个包含更改的新文件。并继续文件中的下一行 (> FILENAME"_updated";next
) - 如果你还在这里,那我们就是常线了。只需将其打印到同一个
_updated
文件:{print [=24=] > FILENAME"_updated"}
- 对该目录中的所有文件执行此操作
*
示例:
~/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", ,,uniquenumber,,, > FILENAME"_updated";next}{print [=11=] > 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]
这是使用 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/^>((.+?)_(.+?))_/>_${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