這一部分我將講解awk腐螟、grep愿汰、sed三個(gè)文本操作的強(qiáng)大利器,三個(gè)命令基本都是以正則表達(dá)式為基礎(chǔ)乐纸。在數(shù)據(jù)分析過(guò)程中衬廷,我們通常需要提取出符合條件的文本、修改文本以進(jìn)行后續(xù)分析汽绢。
我首先簡(jiǎn)單介紹一下正則表達(dá)式吗跋,正則表達(dá)式是一種用于匹配和操作文本的強(qiáng)大工具,它是由一系列普通字符和特殊字符組成的模式,用于描述要匹配的文本模式跌宛。正則表達(dá)式可以在文本中查找酗宋、替換、提取和驗(yàn)證輸入秩冈。正則表達(dá)式由普通字符(例如字母本缠、數(shù)字、空格等)和元字符(特殊字符)組成入问。
字母丹锹、數(shù)字、漢字芬失、下劃線楣黍、以及沒有特殊定義的標(biāo)點(diǎn)符號(hào),都是普通字符棱烂。表達(dá)式中的普通字符租漂,在匹配一個(gè)字符串的時(shí)候,匹配與之相同的字符颊糜。
特殊字符哩治,就是一些有特殊含義的字符,比如^表示匹配輸入字符串的開頭衬鱼,$表示匹配輸入字符串的結(jié)尾等业筏。
接下來(lái)我們分別介紹三個(gè)命令
grep命令更適合單純的查找或匹配文本。它在一個(gè)或多個(gè)文件中搜索字符串模板鸟赫。如果模板包括空格蒜胖,則必須被引用,搜索的結(jié)果被送到標(biāo)準(zhǔn)輸出(終端)抛蚤,不影響原文件內(nèi)容台谢。
#pattern 參數(shù)表示在文件中搜索的文本模式或正則表達(dá)式模式
grep [options] pattern file
#搜索文本中echo字符
grep echo RNA-seq.sh
#搜索位于行首的echo字符串
grep ^echo RNA-seq.sh
#一些常用的參數(shù)包括 -c:統(tǒng)計(jì)匹配上的行數(shù),從而統(tǒng)計(jì)某個(gè)模式在文件中出現(xiàn)的次數(shù)岁经。-i:忽略字符大小寫的差別朋沮;-n:在輸出中顯示匹配到的行的行號(hào),有助于定位缀壤。-o:僅顯示匹配到的字符串朽们,不顯示整行。-v:顯示不被 pattern 匹配到的行诉位,相當(dāng)于[^]。-E 支持使用擴(kuò)展正則表達(dá)式
grep -c ^echo RNA-seq.sh #返回3
sed是一個(gè)“非交互式的”面向字符流的編輯器菜枷。能同時(shí)處理多個(gè)文件多行的內(nèi)容苍糠,可以不對(duì)原文件改動(dòng),把整個(gè)文件輸入到屏幕,可以把只匹配到模式的內(nèi)容輸入到屏幕上啤誊。還可以對(duì)原文件改動(dòng)岳瞭,但是不會(huì)再屏幕上返回結(jié)果拥娄。sed更適合編輯匹配到的文本
sed [option] 'sed command' file
#sed conmmand 包括:
#替換命令 s:語(yǔ)法:s/old_pattern/new_pattern/g,輸出修改后的整個(gè)文件到屏幕上瞳筏,但是沒有改變?cè)募?sed "s/config/fastq/g" RNA-seq.sh
#刪除命令 d:刪除匹配到的行稚瘾。sed '/pattern/d' file.txt。這里是刪除空白行
sed "/^$/d" RNA-seq.sh
#打印命令 p:打印匹配到的行姚炕。sed -n '/pattern/p' file.txt摊欠,其中-n是選項(xiàng)參數(shù),代表只輸出匹配到的行
sed -n "/config/p" RNA-seq.sh
#行追加命令 a:語(yǔ)法:a\text_to_append柱宦,在匹配到的行之后都追加新文本些椒。sed '/pattern/a\new_line_to_append' file.txt
sed "/trim-galore/a\less nohup.out" RNA-seq
#行插入命令 i:i\text_to_insert,在匹配到的行之前插入新文本掸刊。sed '/pattern/i\new_line_to_insert' file.txt免糕。
#行替換命令 c:c\new_text,用新文本替換匹配到的行忧侧。sed '/pattern/c\new_line_to_replace' file.txt
#行號(hào)命令 =:打印每一行的行號(hào)石窑。sed '=' file.txt
sed "=" RNA-seq.sh
#字符集合命令 []:匹配字符集合中的任意一個(gè)字符。sed 's/[aeiou]/_/g' file.txt
sed "s/[R1]/read1/g RNA-seq.sh
#范圍選擇命令 :選擇輸出匹配到的起始和結(jié)束模式之間的內(nèi)容蚓炬。sed -n '/start_pattern/,/end_pattern/p' file.txt
option參數(shù)包括-n :只輸出模式匹配的行
-i :直接在原始文件中進(jìn)行編輯松逊,并將修改后的內(nèi)容寫入到原文件中,而不是輸出到標(biāo)準(zhǔn)輸出试吁。默認(rèn)情況下棺棵,sed 命令會(huì)將處理后的結(jié)果輸出到標(biāo)準(zhǔn)輸出,而不會(huì)修改原始文件熄捍。
-e :在同一行上指定多個(gè) sed 命令烛恤,sed 將按照指定的順序依次執(zhí)行這些命令。此為默認(rèn)選項(xiàng)余耽。sed -e "s/config/fastq/g" -e "/trim-galore/a\less nohup.out" RNA-seq.sh
-f :指定一個(gè)腳本文件缚柏,其中包含了一系列的 sed 命令。sed 將會(huì)按照腳本文件中命令的順序依次執(zhí)行這些命令碟贾。sed -f script.sed RNA-seq.sh
-r :支持?jǐn)U展正則表達(dá)式
awk命令是功能最強(qiáng)大的币喧。awk 更適合格式化文本和處理復(fù)雜文本操作,awk 可以根據(jù)指定的分隔符對(duì)文本進(jìn)行拆分袱耽,提取杀餐、重新組合和輸出字段,支持多種內(nèi)置變量和操作符朱巨,使得文本格式的修改和數(shù)據(jù)的提取非常靈活史翘。awk 可以執(zhí)行條件判斷油湖、模式匹配绸硕、循環(huán)和函數(shù)調(diào)用等復(fù)雜操作分井,適合處理大規(guī)模和結(jié)構(gòu)復(fù)雜的文本數(shù)據(jù)糖驴。
語(yǔ)法結(jié)構(gòu):awk option 'pattern{action}' {filenames}
注意要用單引號(hào) ' '
pattern:是用于匹配輸入數(shù)據(jù)的模式,action是在匹配到模式的行上執(zhí)行的操作
常用options 參數(shù)
-F: 指定輸入字段的分隔符钻蹬,默認(rèn)是空格吼蚁。
-v <變量名>=<值>: 設(shè)置 awk 內(nèi)部的變量值。內(nèi)置和自定義變量前都加 -v 選項(xiàng)
-f <腳本文件>: 指定一個(gè)包含 awk 腳本的文件问欠「未遥可以在文件中編寫較大的 awk 腳本,然后通過(guò) -f 選項(xiàng)將其加載
#使用一個(gè)腳本來(lái)匯總stringtie表達(dá)量結(jié)果溅潜,接下來(lái)以這個(gè)為例進(jìn)行文本操作
vi sample_list.txt
C1 /home/RNA-seq/stringtie/C1_count.gtf
C2 /home/RNA-seq/stringtie/C2_count.gtf
C3 /home/RNA-seq/stringtie/C3_count.gtf
E1 /home/RNA-seq/stringtie/E1_count.gtf
E2 /home/RNA-seq/stringtie/E2_count.gtf
E3 /home/RNA-seq/stringtie/E3_count.gtf
常用的awk內(nèi)置變量术唬,包括
#FS:輸入字段分隔符。同-F參數(shù)滚澜,
awk -F "\t" ‘{print$1}’ sample_list.txt
awk -v FS="\t" ‘{print$1}’ sample_list.txt
#OFS:輸出字段分隔符粗仓。例如將txt文件每行的第1和2字段提取出來(lái),并將分隔符設(shè)置為制表符(Tab)輸出
awk -v OFS="\t" '{print $2, $1}' sample_list.txt设捐,
#RS:輸入記錄分隔符借浊。用于定義 awk 讀取輸入時(shí)的記錄分隔符。默認(rèn)值為換行符 \n萝招,即每行被視為一個(gè)記錄蚂斤。
#ORS:輸出記錄分隔符。
#NF:代表輸出記錄中的字段數(shù)槐沼。$NF 表示最后一個(gè)字段曙蒸。$(NF-1)是倒數(shù)第2列
awk '{print "Number of fields:", NF, "Last field:", $NF}' sample_list.txt
#輸出Number of fields: 2 Last field: /home/RNA-seq/stringtie/C1_count.gtf
#Number of fields: 2 Last field: /home/RNA-seq/stringtie/C2_count.gtf
#...
#NR:代表輸出記錄(行)號(hào)。每個(gè)輸出記錄一個(gè)行號(hào)岗钩。后可跟多個(gè)文件纽窟,第二個(gè)文件行號(hào)繼續(xù)從第一個(gè)文件最后行號(hào)開始。
#$0:表示整行內(nèi)容兼吓。$1, $2, ...:表示第1臂港、2個(gè)字段。
$awk '{print NR, $0}' sample_list.txt
awk 支持一系列操作符视搏,用于執(zhí)行數(shù)學(xué)運(yùn)算审孽、字符串操作和邏輯比較
算術(shù)操作符:+、- 浑娜、佑力、/:除法、%:取余筋遭、^:冪運(yùn)算打颤。
賦值操作符:=:賦值杂数、+=:加等于、-=:減等于瘸洛、=:乘等于、/=:除等于次和、%=:取余等于反肋。例如num=10 num+=5就是先10+5,再將15賦值給num
比較操作符:==:等于踏施、!=:不等于石蔗、<:小于、>:大于畅形、<=:小于等于养距、>=:大于等于。
邏輯操作符:&&:邏輯與日熬、||:邏輯或棍厌、!:邏輯非。
字符串操作符 :"~" 匹配正則表達(dá)式竖席、"!~" :不匹配正則表達(dá)式耘纱。例如awk '$0 ~ /C1/' sample_list.txt 輸出所有包含C1的行
我以cut-tag數(shù)據(jù)分析中的文件為例,因?yàn)檗D(zhuǎn)錄組數(shù)據(jù)比較簡(jiǎn)單毕荐,無(wú)需復(fù)雜的awk命令
#首先以bedpe文件為例束析,用于表示雙末端bed文件,每一列分別為chrom1 start1 end1 chrom2 start2 end2 name score strand1 strand2
#將文件中第一列等于第四列(在同一染色體上)且終止-起始<1000的行打印出來(lái)
awk '$1==$4 && $6-$2 < 1000 {print $0}' C1_bowtie2.bed
#輸出第6列減去第2列的絕對(duì)值憎亚,即片段長(zhǎng)度
#定義一個(gè)函數(shù) abs 用于計(jì)算絕對(duì)值员寇,renturn:函數(shù)的返回值,(condition) ? (if_true) : (if_false)第美,如果x<0.0蝶锋,返回-x,否則返回x斋日。
awk -F'\t' 'function abs(x){return ((x < 0.0) ? -x : x)} {print abs($9-$2)}' C1_bowtie2.bed
其他常用于文本操作的命令還有一些cut命令牲览、sort命令、uniq命令
cut 命令用于從文件或標(biāo)準(zhǔn)輸入中提取指定字段或字符位置的數(shù)據(jù)恶守,可以根據(jù)字段的分隔符將每行數(shù)據(jù)分割成多個(gè)字段第献,并選擇需要提取的字段進(jìn)行輸出
cut [選項(xiàng)] [文件]
常用選項(xiàng):
#-b 或 --bytes:按字節(jié)選擇,適合處理二進(jìn)制文件兔港。提取每行的第1到5個(gè)字節(jié)
cut -b 1-5 file
#-c 或 --characters:按字符選擇庸毫,適合處理文本文件。提取每行的第1到5個(gè)字符
cut -c 1-5 file
#-f 或 --fields:按字段選擇衫樊,字段是以指定分隔符分隔的部分飒赃。-d 或 --delimiter:指定字段分隔符利花,默認(rèn)為制表符。如以逗號(hào)為分隔符载佳,提取每行的第2個(gè)字段
cut -f 2 -d "," file
#-s, --only-delimited:不打印不包含分隔符的行炒事。例如,使用逗號(hào)分隔并忽略不含逗號(hào)的行
cut -d "," -f 2 -s file
#--complement:顯示除了指定部分以外的所有部分蔫慧。例如挠乳,顯示除第1到3個(gè)字符以外的所有字符
cut -c 1-3 --complement file
#--output-delimiter="," 用于指定輸出字段的分隔符
sort 命令用于將文本文件內(nèi)容加以排序。以行為單位來(lái)排序姑躲。
sort [-bcdfimMnr][-o<輸出文件>][-t<排序時(shí)用的分隔符>][-k field1,field2][文件]
#-b 忽略每行前面開始出的空格字符
#-c 檢查文件是否已經(jīng)按照順序排序睡扬,如果沒有排序則輸出錯(cuò)誤信息。
#-d 排序時(shí)黍析,處理英文字母卖怜、數(shù)字及空格字符外,忽略其他的字符阐枣。以字典順序排序
#-f 忽略大小寫進(jìn)行排序马靠。
#-m 將幾個(gè)排序好的文件進(jìn)行合并。
sort -m file1.txt file2.txt
#-n 依照數(shù)值的大小排序
#-r 以相反的順序來(lái)排序
#-k field1,field2指定按字段排序侮繁,可以指定開始和結(jié)束字段虑粥。識(shí)別字段分隔符(默認(rèn)空格)。
#-k用于指定排序的鍵宪哩,而后面跟隨的 n 表示按照數(shù)字進(jìn)行排序娩贷。1,1 表示只對(duì)第一個(gè)字段進(jìn)行排序,即只考慮第一個(gè)字段的值锁孟,不考慮后續(xù)的字段彬祖。k2,2n:表示在第一個(gè)字段相同的情況下,只按照第二個(gè)字段進(jìn)行排序品抽,即按照數(shù)字的大小排序储笑,而不是按照字典序排序。
sort -k 1,1 -k 2,2n file
#排序依據(jù)為第二字段的全部?jī)?nèi)容
sort -k 2 file
uniq 命令用于檢查及刪除文本文件中重復(fù)出現(xiàn)的行列圆恤,一般與 sort 命令結(jié)合使用突倍,因?yàn)閡niq 需要排序的輸入才能正確地識(shí)別重復(fù)的行。
uniq [選項(xiàng)] [輸入文件][輸出文件]
常用的選項(xiàng)包括
#-c 顯示每行重復(fù)出現(xiàn)的次數(shù)
sort file | uniq -c
#-d:僅顯示重復(fù)的行
sort file | uniq -d
#-u:僅顯示唯一的行盆昙,即沒有重復(fù)的行
#-i:忽略大小寫
#-f N:忽略每行的前N個(gè)字段
sort file | uniq -f 2
#-s N:忽略每行的前N個(gè)字符
#-w N:比較每行的前N個(gè)字符羽历。例如,比較每行的前5個(gè)字符淡喜,以識(shí)別重復(fù)行秕磷,輸出每行前5個(gè)字符唯一的行
sort file | uniq -w 5
還是以cut&tag數(shù)據(jù)分析為例
#代碼主要用于計(jì)算從一組 SAM 文件中提取的雙端比對(duì)的片段長(zhǎng)度分布,并將結(jié)果保存到相應(yīng)的文件中
#samtools view 命令用于查看 SAM/BAM 文件內(nèi)容炼团。-F 0x04用于過(guò)濾掉那些未比對(duì)上的序列
for name in $root/2.map/bowtie2_result/*_bowtie2.sam
do
samtools view -F 0x04 $name | \
#awk -F'\t' 指定輸入文件以TAB為字段分隔符澎嚣。定義一個(gè) abs 函數(shù)疏尿,用于計(jì)算絕對(duì)值。打印第九列(即片段長(zhǎng)度)的絕對(duì)值
awk -F'\t' 'function abs(x){return ((x < 0.0) ? -x : x)} {print abs($9)}' | \
#sort 對(duì)片段長(zhǎng)度進(jìn)行排序易桃。uniq -c 統(tǒng)計(jì)每個(gè)不同片段長(zhǎng)度出現(xiàn)的次數(shù)褥琐。
#-v OFS="\t" 設(shè)置輸出字段分隔符為制表符。輸出第二列(片段長(zhǎng)度)和第一列(計(jì)數(shù))的一半晤郑。這里的 $1/2 是因?yàn)?uniq -c 輸出的計(jì)數(shù)實(shí)際上是兩次比對(duì)的計(jì)數(shù)結(jié)果踩衩,需要除以 2 得到實(shí)際的配對(duì)數(shù)量。
sort | uniq -c | awk -v OFS="\t" '{print $2, $1/2}' \
#將處理結(jié)果重定向到 $path/2.map/fragmentLen/ 目錄中的新文件中贩汉。
> $path/2.map/fragmentLen/$(basename $name "_bowtie2.sam")_fragmentLen.txt
done
#在 BEDPE文件中,每一行代表一個(gè)基因組區(qū)域或一個(gè)比對(duì)結(jié)果锚赤,第 1 列(chrom1):第一個(gè)讀取的染色體名稱匹舞。第 2 列(start1):第一個(gè)讀取的起始位置。第 3 列(end1):第一個(gè)讀取的結(jié)束位置线脚。第 4 列(chrom2):第二個(gè)讀取的染色體名稱赐稽。第 5 列(start2):第二個(gè)讀取的起始位置。第 6 列(end2):第二個(gè)讀取的結(jié)束位置浑侥。
#首使用 cut 命令提取C1_bowtie2.clean.bed指定列(第 1姊舵、2 和 6 列)。然后按第 1 列(染色體)寓落、第 2 列(比對(duì)基因的起始位置)和第 3 列(比對(duì)基因結(jié)束位置)排序括丁。再將最終結(jié)果保存到指定文件。
#這段代碼的作用就是提取關(guān)鍵信息伶选,即比對(duì)上的基因位置史飞,并按基因在染色體上的位置進(jìn)行排序
cut -f 1,2,6 C1_bowtie2.clean.bed | sort -k1,1 -k2,2n -k3,3n > C1_bowtie2.fragment.bed
這一部分比較復(fù)雜,一些比較簡(jiǎn)單的轉(zhuǎn)錄組分析很少使用仰税,大家可以結(jié)合自己的數(shù)據(jù)進(jìn)行學(xué)習(xí)构资。目前這是常用Linux命令的最后一部分了,歡迎大家討論交流陨簇,我也會(huì)在分析過(guò)程中繼續(xù)總結(jié)吐绵,查漏補(bǔ)缺。