Bash

如何從fasta文件中隨機提取200個字元的子字元串

  • December 5, 2020

是否有任何 Linux 命令可以用來從文件中提取序列?例如,一個文件包含一百萬行,我們只想從該文件中隨機抽取 200 個字元的序列(不考慮標題)。

對於隨機,我的意思是每 200 個序列都有相同的機率被選擇,並且選擇的子串都不是重複的。

我正在考慮從這樣的fasta文件中隨機提取這200個字元的序列(不考慮標題):

>NC_001416.1 Enterobacteria phage lambda, complete genome
GGGCGGCGACCTCGCGGGTTTTCGCTATTTATGAAAATTTTCCGGTTTAAGGCGTTTCCGTTCTTCTTCG
TCATAACTTAATGTTTTTATTTAAAATACCCTCTGAAAAGAAAGGAAACGACAGGTGCTGAAAGCGAGGC
TTTTTGGCCTCTGTCGTTTCCTTTCTCTGTTTTTGTCCGTGGAATGAACAATGGAAGTCAACAAAAAGCA
GCTGGCTGACATTTTCGGTGCGAGTATCCGTACCATTCAGAACTGGCAGGAACAGGGAATGCCCGTTCTG
CGAGGCGGTGGCAAGGGTAATGAGGTGCTTTATGACTCTGCCGCCGTCATAAAATGGTATGCCGAAAGGG
ATGCTGAAATTGAGAACGAAAAGCTGCGCCGGGAGGTTGAAGAACTGCGGCAGGCCAGCGAGGCAGATCT
CCAGCCAGGAACTATTGAGTACGAACGCCATCGACTTACGCGTGCGCAGGCCGACGCACAGGAACTGAAG
AATGCCAGAGACTCCGCTGAAGTGGTGGAAACCGCATTCTGTACTTTCGTGCTGTCGCGGATCGCAGGTG
AAATTGCCAGTATTCTCGACGGGCTCCCCCTGTCGGTGCAGCGGCGTTTTCCGGAACTGGAAAACCGACA
TGTTGATTTCCTGAAACGGGATATCATCAAAGCCATGAACAAAGCAGCCGCGCTGGATGAACTGATACCG
GGGTTGCTGAGTGAATATATCGAACAGTCAGGTTAACAGGCTGCGGCATTTTGTCCGCGCCGGGCTTCGC
TCACTGTTCAGGCCGGAGCCACAGACCGCCGTTGAATGGGCGGATGCTAATTACTATCTCCCGAAAGAAT
CCGCATACCAGGAAGGGCGCTGGGAAACACTGCCCTTTCAGCGGGCCATCATGAATGCGATGGGCAGCGA
CTACATCCGTGAGGTGAATGTGGTGAAGTCTGCCCGTGTCGGTTATTCCAAAATGCTGCTGGGTGTTTAT
GCCTACTTTATAGAGCATAAGCAGCGCAACACCCTTATCTGGTTGCCGACGGATGGTGATGCCGAGAACT
TTATGAAAACCCACGTTGAGCCGACTATTCGTGATATTCCGTCGCTGCTGGCGCTGGCCCCGTGGTATGG
CAAAAAGCACCGGGATAACACGCTCACCATGAAGCGTTTCACTAATGGGCGTGGCTTCTGGTGCCTGGGC
GGTAAAGCGGCAAAAAACTACCGTGAAAAGTCGGTGGATGTGGCGGGTTATGATGAACTTGCTGCTTTTG
ATGATGATATTGAACAGGAAGGCTCTCCGACGTTCCTGGGTGACAAGCGTATTGAAGGCTCGGTCTGGCC
AAAGTCCATCCGTGGCTCCACGCCAAAAGTGAGAGGCACCTGTCAGATTGAGCGTGCAGCCAGTGAATCC
CCGCATTTTATGCGTTTTCATGTTGCCTGCCCGCATTGCGGGGAGGAGCAGTATCTTAAATTTGGCGACA
AAGAGACGCCGTTTGGCCTCAAATGGACGCCGGATGACCCCTCCAGCGTGTTTTATCTCTGCGAGCATAA
TGCCTGCGTCATCCGCCAGCAGGAGCTGGACTTTACTGATGCCCGTTATATCTGCGAAAAGACCGGGATC

因此,我可以作為範例獲得這樣的序列子集:

GCATACCAGGAAGGGCGCTGGGAAACACTGCCCTTTCAGCGGGCCATCATGAATGCGATGGGCAGCGACTACATCCGTGAGGTGAATGTGGTGAAGTCTGCCCGTGTCGGTTATTCCAAAATGCTGCTGGGTGTTTATGCCTACTTTATAGAGCATAAGCAGCGCAACACCCTTATCTGGTTGCCGACGGATGGTGATGC

為了能夠對隨機 200 個字元長度的序列進行多次快速選擇,保存一份不帶換行符的 fasta 文件副本很方便(也不包括標題)。

< file.fasta tail -n+2 | tr -d '\n' > newfile

因此,您將隨機選擇起始字元,而不會碰到任何換行符和/或進行任何計算來處理它。另外我假設wc -c < file(or wc -m) 並stat -c "%s" file給出相同的結果(對於通常的內容、語言環境等,請先檢查它),所以我們使用stat哪個返回更快。

對於帶有n字元的文件,可用的選項是n-200,我們從可能的起始位置排除最後 200 個字元,因為它們不能形成 200 個字元的長字元串。

shuf選擇範圍的隨機數,和with1,n-200的組合將提取字元串。head``tail``-c

n=$(stat -c "%s" newfile)
r=$(shuf -i1-"$((n-200+1))" -n1)
< newfile tail -c+"$r" | head -c200

您可以多次呼叫它以獲得許多不同的獨立隨機選擇,這意味著即使是相同或重疊的序列。

如果您希望您的選擇遵循其他標準,例如不在文件中的同一位置和/或不重疊,則必須解析來自同一shuf命令的隨機數(具有更高的-n值)。或者,為了不重疊,丟棄任何與現有值接近 200 的新值。

如果您想選擇 x 個隨機獨立但唯一的序列,您可以開始生成隨機行,刪除重複項並將其中的 x 個保留為head,例如獲取其中的 10 個:

while true; do sh test.sh; printf "\n"; done | awk '!seen[$0]++' | head

引用自:https://unix.stackexchange.com/questions/622425