題目是這樣的:
統(tǒng)計SRR1039510_1.fastq.gz堿基總數(shù) 1575000
由于上一題已經(jīng)列出了該文件中所有的序列
$ zcat SRR1039510_1.fastq.gz | sed -n '2~4p' | head
TGGGAGGCTGAGGCAGGAGAATCACTTAAACCTGGGAGGCAGAGGTTACAGTGAGCCGAGATT
AAAGAAGGCGACAGTGAGAAGGAGTCCGAGAAGAGTGATGGAGACCCAATAGTCGATCCTGAG
CTGCTGGGCCCCAAGGTCCTCCTGGTCCCAGTGGTGAAGAAGGAAAGAGAGGCCCTAATGGGG
CTTGGCTGCAGCCATCCCGCTTAGCCTGCCTCACCCACACCCGTGTGGTACCTTCAGCCCTGG
TGAGACAGGTAATTCAGTATAGTAGATTAATATTTTTAATATATATTTTCCCTTAAGATTTCC
ATTTCTCAGTGTAGAAATCATGTCTTCTTAATTGCTGAACCTTACTGCAAAAACTTGTGATGT
ATCAAGAATACCAAAACAGTTTCCTAATATACAGTATTTGAAAGTGCTTGCCATATTGGCTCT
CTCATTTTCATCTTCACCATCAACAGAGAGAGCAGCATACTTGCTTGCAGAACTGAACTTAGA
TCCAACCGCAGCTTGGCATCTTCGGTGGCCTGCAGCTCGTCCTCCAGCTCTTCCAGCTGCGTC
CGGCCTCCCAAAGTGCTGGGATTACAGGCATGAGCCACCGCGCTCTGCGAGGTACTTTTTCTA
于是我想,這還不簡單,直接wc -c
$ zcat SRR1039510_1.fastq.gz | sed -n '2~4p' | wc -c
1600000
但是,這居然和答案不對!居然多統(tǒng)計了25000.。。。等等,25000不就是第一題統(tǒng)計多少讀長的答案嗎
$ zcat SRR1039510_1.fastq.gz | grep '@SRR'| wc -l
25000
插播一點題外話,昨天“小二黑”直接統(tǒng)計行數(shù)
$ zcat SRR1039510_1.fastq.gz | wc -l
100000
老師說,再計算一下就好:每4行一個read,除以4就好了。于是我聯(lián)想起之前“萌哥”講過bc這個命令,還自己搞了一個“花樣”出來:
$ echo $(zcat SRR1039510_1.fastq.gz | wc -l)
100000
$ echo $(zcat SRR1039510_1.fastq.gz | wc -l)/4
100000/4
$ echo $(zcat SRR1039510_1.fastq.gz | wc -l)/4 | bc
25000
這姑且不說。
多統(tǒng)計出來25000個堿基,看起來似乎是每一行多統(tǒng)計了一個字符,那么多出來的這個字符是什么呢?聯(lián)想一下之前在某處似乎聽過,每行末尾的換行符是會計算進去的。于是我cat -A了一下。
$ zcat SRR1039510_1.fastq.gz | sed -n '2~4p' | cat -A | head
TGGGAGGCTGAGGCAGGAGAATCACTTAAACCTGGGAGGCAGAGGTTACAGTGAGCCGAGATT$
AAAGAAGGCGACAGTGAGAAGGAGTCCGAGAAGAGTGATGGAGACCCAATAGTCGATCCTGAG$
CTGCTGGGCCCCAAGGTCCTCCTGGTCCCAGTGGTGAAGAAGGAAAGAGAGGCCCTAATGGGG$
CTTGGCTGCAGCCATCCCGCTTAGCCTGCCTCACCCACACCCGTGTGGTACCTTCAGCCCTGG$
TGAGACAGGTAATTCAGTATAGTAGATTAATATTTTTAATATATATTTTCCCTTAAGATTTCC$
ATTTCTCAGTGTAGAAATCATGTCTTCTTAATTGCTGAACCTTACTGCAAAAACTTGTGATGT$
ATCAAGAATACCAAAACAGTTTCCTAATATACAGTATTTGAAAGTGCTTGCCATATTGGCTCT$
CTCATTTTCATCTTCACCATCAACAGAGAGAGCAGCATACTTGCTTGCAGAACTGAACTTAGA$
TCCAACCGCAGCTTGGCATCTTCGGTGGCCTGCAGCTCGTCCTCCAGCTCTTCCAGCTGCGTC$
CGGCCTCCCAAAGTGCTGGGATTACAGGCATGAGCCACCGCGCTCTGCGAGGTACTTTTTCTA$
然后突然想起
$ zcat SRR1039510_1.fastq.gz |head
@SRR1039510.1 HWI-ST177:290:C0TECACXX:1:1101:1373:2104 length=63
TGGGAGGCTGAGGCAGGAGAATCACTTAAACCTGGGAGGCAGAGGTTACAGTGAGCCGAGATT
+SRR1039510.1 HWI-ST177:290:C0TECACXX:1:1101:1373:2104 length=63
HJJJIJJJJJJJJIJJJGHHIJIIIIIIJJEHGGIJGIJIJJIJHHHGGFFDFFFDEDDDBDC
@SRR1039510.2 HWI-ST177:290:C0TECACXX:1:1101:1340:2124 length=63
AAAGAAGGCGACAGTGAGAAGGAGTCCGAGAAGAGTGATGGAGACCCAATAGTCGATCCTGAG
+SRR1039510.2 HWI-ST177:290:C0TECACXX:1:1101:1340:2124 length=63
HJJJJJJJJJJJIJIIGIJJJJGJHJJJHHDFFFE@CEEEDDDDDDDDDDDDDDDBDDDDDDD
@SRR1039510.3 HWI-ST177:290:C0TECACXX:1:1101:1273:2183 length=63
CTGCTGGGCCCCAAGGTCCTCCTGGTCCCAGTGGTGAAGAAGGAAAGAGAGGCCCTAATGGGG
人家這里都告訴你每個read的長度是63,于是計算一下
$ echo 63*25000 |bc
1575000
果然就是正確答案。
說明:1,的確每行多統(tǒng)計了一個字符;2,且多統(tǒng)計的是行末的換行符。
然后我想怎么把準確的數(shù)字統(tǒng)計出來,那就需要把行末的換行符去掉。于是:
$ zcat SRR1039510_1.fastq.gz | sed -n '2~4p' | sed 's/\n//g' | wc -c
1600000
發(fā)現(xiàn)并沒有刪除掉換行符。于是陷入了各種嘗試,驗證,懷疑……
最后在網(wǎng)上搜到了一個答案:
$ zcat SRR1039510_1.fastq.gz | sed -n '2~4p' | sed -e ':a;N;s/\n//g;ta' | wc -c
1575001
這個。。。似乎是去掉換行符了,但是。。怎么還多一個。。。
于是又開始猜想,可能是最后一個換行符沒有刪掉,為什么沒有刪掉呢,可能這個命令不適合我,需要再調(diào)整。于是又學習了這里面的冒號:t a N都是些什么意思,怎么用的。。。。
然后發(fā)現(xiàn),確實沒有錯,就是最后一個換行符沒有刪掉。
zcat SRR1039510_1.fastq.gz | sed -n '2~4p' | sed -e ':a;N;s/\n//g;ta' | cat -A
刷屏中……GATGGGGATCTGGCTCATGTCCAAAGGTGCAATATCAAGGAAGGGCAGGCGTGATGGCTTATTTGTTTTGTATTCAATGAATTTACACAGTCTCAGATTATCTCCTAACTCCCCACAAGACACTTATTTATTCCAAAGAAAGAACCAAAACTCCTGATGATGAAGGCCAGGGCCTCACGGGGCACCTCTCGGTTCAGGAAGAACTTCCATCGCTCGGCTGTTGGACCGGAACCAGGATGCAACTGAGGACACTGACGTGCAGAACATGAGGTGGCTTCTTGCAGTTCTCCCTGTAGACCCACGATACCAGCTGTCGGTTTTGTCAATGAAGTCCAGGCTCAGGCCCCCGGGCCCGATCATGGCCCCAGTCCGCACAGAGCGCCCGGCCCTGGCCGGTGTGGACAGAACTGGGGGCAAAAACAAAAAAGAAGGAAGGAAGGAAAGAAAGAAATGGGTAT$
N在這里把所有的序列合成1行了,然后再輸出的,最后帶一個換行符。
到這里徹底放棄sed了,腦霧之后想起tr還可以用,于是又嘗試一下。
$ zcat SRR1039510_1.fastq.gz | sed -n '2~4p' | tr -d '\n' | wc -c
1575000
終于得到了正確答案!
但是為什么sed替換掉換行符,最后一個還留著呢?為什么不用標簽來寫script就一個也替換不掉呢?
因為(參考:http://yysfire.github.io/linux/sed-usage-summary.html 或者https://blog.csdn.net/u011729865/article/details/71773840)
sed 維護著兩個數(shù)據(jù)緩存區(qū):模式空間和保留空間。兩者均被初始化為空。
sed 對輸入的每一行運行一次如下所述的執(zhí)行周期:首先,sed 從輸入流中讀入一行,并刪除行末的換行符,將此行的內(nèi)容放入模式空間。然后,腳本里的命令被執(zhí)行;可以對每一個命令指定地址(地址相當于一種條件,只有條件被滿足,才會執(zhí)行緊跟其后的命令。當?shù)竭_腳本的結(jié)尾,模式空間的內(nèi)容(如果之前行末的換行符被刪除,此時會被加回來)被寫入到輸出流(除非使用了選項'-n')。然后,對下一行開始下一個執(zhí)行周期。
標簽的使用參考上述地址或者:http://blog.chinaunix.net/uid-20943515-id-403.html
man一下sed,發(fā)現(xiàn)有個-z選項,可以用空字符作為每行的分割
-z, --null-data
separate lines by NUL characters
$ zcat SRR1039510_1.fastq.gz | sed -n '2~4p' | sed -z 's/\n//g'| wc -c
1575000
其實不糾結(jié)于sed,可以用awk來實現(xiàn):
$ zcat SRR1039510_1.fastq.gz | sed -n '2~4p' | awk '{print $0}' ORS='' | wc -c
1575000