正則表達式(regular expression, regex)是一個重要且實用的概念,我時常提起卻從未細談。一怕能力不夠說不清楚反而會誤導(dǎo)人,二是已經(jīng)有無數(shù)前人撰文介紹??紤]日常用到的grep,sed,awk里經(jīng)常需要用到正則表達式,于是開一個小系列,介紹如何在grep,sed,awk中適用正則。
什么是正則表達式
正則表達式(regular expression)的概念,最初來自于20世紀(jì)40年代的兩位神經(jīng)學(xué)家(Warren McCulloch, Walter Pitts)研究神經(jīng)元時提出的想法。后來數(shù)學(xué)家Stephen Kleene在代數(shù)學(xué)中正式描述了這種被他稱之為“正則集合”的模型。并且,他還發(fā)明了一套簡潔的方法表示正則集合,也就是正則表達式。
目前最快速的文本搜索工具grep就內(nèi)置了正則表達式。grep起源于Unix中的ed編輯器的一條命令g/Regular Expression/p, 讀作“Global Reular Expression Print”,即運用正則表達式的全局輸出。由于這個功能太過實用,于是就從ed中獨立出來,演變成了grep以及擴展版本的egrep。都知道grep因為有正則表達式所以很強大,但是正則表達式為何如此強大呢?
正則表達式的強大之處在于它是一套語法,分為兩個部分,元字符(metacharacters)和普通文本字符(normal text characters)。
以語言類比,“我愛正則表達式”這句話可以抽象成“主謂賓”結(jié)構(gòu),主語是"我",謂語是"愛",賓語是“正則表達式”。這種語法還適用于其他語言,比如說英語就是"I love regular expression". 這種語法結(jié)構(gòu)就是元字符,而構(gòu)成句子的語言就是普通文字字符。
元字符一覽
正則表達式有很多流派,不同流派之間的差異在于對元字符的支持程度。以下的元字符適用于GNU版本的grep, sed, awk. mac自帶的是BSD版本。
匹配單個字符的元字符:
| 元字符 | 匹配對象 |
|---|---|
| . | 匹配單個任意字符 |
| [...] | 匹配單個列出的字符 |
| [^...] | 匹配單個未列出的字符 |
| \char | 轉(zhuǎn)義元字符成普通字符 |
提供技術(shù)功能的元字符
| 元字符 | 匹配對象 |
|---|---|
| ? | 匹配0或1次 |
| * | 匹配0到n次 |
| + | 至少一次,最多不限 |
| {min,max} | 至少min次, 最多max次 |
匹配位置的元字符
| 元字符 | 匹配對象 |
|---|---|
| ^ | 匹配一行的開頭 |
| $ | 匹配一行的結(jié)尾 |
其他元字符
| 元字符 | 匹配對象 |
|---|---|
| 豎線 | 匹配任意分割的表達式 |
| (...) | 限定多選結(jié)構(gòu)的范圍,標(biāo)注量詞的作用范圍,為反向引用捕獲元素 |
| \1, \2 | 反向引用元素 |
在grep中使用正則表達式
grep的強大之處它所做的事情就只有在文本搜索”正則表達式“定義的模式(pattern),如果找到就打印出來。可以使用man egrep查看所支持的參數(shù)。
egrep [options] pattern [file]
egrep [options] [-e pattern]... [-f FILE]... [FILE...]
# 參數(shù)參數(shù)
-e PATTERN: 定義多個模式
-f FILE: 從文本中讀取模式
-w: 匹配整個單詞
-v: 反向匹配
-i: 忽略大小寫
-x: 僅僅選擇整行匹配結(jié)果
-c: 計數(shù)
-n: 輸出表明行號
-A/-B NUM: 同時輸出后/前幾行
注: grep有基礎(chǔ)和擴展兩個模式,基礎(chǔ)模式支持的元字符較少,而egrep表示擴展的grep,支持的元字符較多。
檢查測序結(jié)果的接頭
在分析的質(zhì)控階段,需要檢查給出的結(jié)果是否含有接頭(adapter)。除了fastqc, 還能用grep檢測是否有接頭序列。
你可以去illumina的官網(wǎng)根據(jù)公司測序的protocol查找對應(yīng)的接頭:
https://support.illumina.com/downloads/illumina-customer-sequence-letter.html
或者是直接看FASTQC的配置文件中檢測的接頭

# 下載測試數(shù)據(jù)
fastq-dump -X 10000 SRR1553606 --split-files
然后用部分的接頭對fastq文件進行搜索
egrep -B1 'TCGGAA' SRR1553606_1.fastq

被找到的序列并非出現(xiàn)最開頭,你可能希望是開頭有幾個其他堿基,然后跟著接頭序列.
egrep -B1 '^[ATGC]{0,5}TCGGAA' SRR1553606_1.fastq

基因搜索
一般而言,大家都回去TAIR上查找基因的區(qū)間。但是實際上我們可以先下載好擬南芥參考基因組及其注釋文件,然后直接用正則表達式確定區(qū)間,用bedtools提取序列進行了。
# 下載序列
wget -c -4 -q http://www.arabidopsis.org/download_files/Genes/TAIR10_genome_release/TAIR10_chromosome_files/TAIR10_chr_all.fas
# 下載GFF文件
wget -c -4 -q http://www.arabidopsis.org/download_files/Genes/TAIR10_genome_release/TAIR10_gff3/TAIR10_GFF3_genes.gff
# 基因的信息
wget http://www.arabidopsis.org/download_files/Genes/TAIR10_genome_release/gene_description_20131231.txt.gz
在注釋文件中查找某一個基因如SPL9, 并獲取他的位置信息.
grep -i -w 'spl9' gene_description_20131231.txt

grep -e 'AT2G42200.1' TAIR10_GFF3_genes.gff | grep 'mRNA'

當(dāng)然以上命令可以連成管道, 并且和bedtools合用,就可用直接獲取DNA序列。
bedtools getfasta -fi TAIR10.fa -bed <(grep -i -w 'spl9' gene_description_20131231.txt | cut -f 1 | xargs -i grep -i {} TAIR10_GFF3_genes.gff | grep mRNA | cut -f '1,4,5')
你可以將其定義成一個函數(shù),存放在配置文件中, 隨后就能進行調(diào)用該函數(shù)。

