基于逗号分隔表的字符串有效重命名

时间:2018-08-14 23:49:55

标签: bash rename

我想基于逗号分隔的表重命名长文件中的多个单独条目。我想出了一种方法,但是我觉得它效率很低,我想知道是否有更好的方法可以做到这一点。

我的文件包含超过3万个这样的条目:

>Gene.1::Fmerg_contig0.1::g.1::m.1 Gene.1::Fmerg_contig0.1::g.1
TPAPHKMQEPTTPFTPGGTPKPVFTKTLKGDVVEPGDGVTFVCEVAHPAAYFITWLKDSK
>Gene.17::Fmerg_Transcript_1::g.17::m.17 Gene.17::Fmerg_Transcript_1::g.17  
PLDDKLADRVQQTDAGAKHALKMTDEGCKHTLQVLNCRVEDSGIYTAKATDENGVWSTCS
>Gene.15::Fmerg_Transcript_1::g.15::m.15 Gene.15::Fmerg_Transcript_1::g.15
AQLLVQELTEEERARRIAEKSPFFMVRMKPTQVIENTNLSYTIHVKGDPMPNVTFFKDDK

包含重命名信息的表如下:

original,renamed
Fmerg_contig0.1,Fmerg_Transcript_0
Fmerg_contig1.1,Fmerg_Transcript_1
Fmerg_contig2.1,Fmerg_Transcript_2

我想出的效率不高的解决方案如下:

#!/bin/bash
#script to revert dammit name changes

while read line; do
    IFS="," read -r -a contig <<< "$line"
    sed -i "s|${contig[1]}|${contig[0]}|g" Fmerg_final.fasta.transdecoder_test.pep
done < Fmerg_final.fasta.dammit.namemap.csv

但是,这意味着sed在要重命名的每个条目上遍历表一次。

我可以想象有一种方法只能访问每一行一次,并以这种方式遍历名称列表,但是我不确定如何解决这个问题。我选择bash的原因是这是我最流利的语言。但是如果Perl或python提供了更简单的解决方案,那么我对使用Perl或python并不感到不利。

1 个答案:

答案 0 :(得分:0)

这是On问题,您使用On解决方案解决了它,因此我认为它效率不高。但是,如果您对bash感到满意,那么可以做更多的事情。

分而治之。 我已经做过很多次了,因为您可以将工作时间减少到接近处理一件物品的时间..

使用此伪代码,我调用一个将30K文件切成X个部分的方法,然后在带有&选项的循环中调用它作为线程运行。

declare -a file_part_names

# cut files into parts
function cut_file_into_parts() {
    orig_file="$1"
    number_parts="$1"

}

# call method to handle renaming a file
function rename_fields_in_file() {
    file_part="$1"
    while read line; do
    IFS="," read -r -a contig <<< "$line"
    sed -i "s|${contig[1]}|${contig[0]}|g" "$tmp_file"
done < "$file_part"
}

# main
cut_file_into_parts "Fmerg_final.fasta.dammit.namemap.csv"

for each file_part ;do
   if threads_pids < 100

      rename_fields_in_file $each &
   else
      sleep 10
   fi
done
wait
#Now that you have a pile of temp files processed, combine them all.

for each temp file do
  temp_$i.txt >> final_result.txt
done

总而言之,将大文件切成500个tmp文件,在/ tmp / folder中标记为file1,file2等。然后一次遍历它们,但是在子进程同时启动它们(最多运行100个)时启动它们,通过检查是否超过100个不执行任何操作(休眠10个)(如果添加了多个)则保持管道满载。完成后,再执行一次循环即可将file1_finish.txt结合到file2_finish.txt等,这非常快。

注意:如果太多,您总是可以将文件分解并为每个文件调用相同的脚本X次,而不使用线程。