Linux處理文本的三駕馬車—awk命令常用功能

Linux處理文本的第三駕馬車—awk命令

AWK是一種優(yōu)良的文本處理工具,Linux及Unix環(huán)境中現(xiàn)有的功能最強(qiáng)大的數(shù)據(jù)處理引擎之一https://zh.wikipedia.org/wiki/AWKawk也稱gawk烫幕,編程語言,可對文本和數(shù)據(jù)進(jìn)行處理。awk比grep或sed難度大一些,在這兒主要學(xué)習(xí)它常用的命令行處理文本方法敌完,除了能處理文本,它比sed和grep多一個功能羊初,即可以處理數(shù)據(jù)(如加減乘除)滨溉。

常見參數(shù)

-F,fields长赞,設(shè)置字段(一列)分隔符;(聯(lián)想到cut -d)

-v晦攒,var=value定義awk程序中的一個變量及其默認(rèn)值(變量在代碼里可以用,在外面定義在里面用)

常見用法


awk [options] '{script}' file


中間有一個代碼部分{script}得哆,作用和sed命令很像

代碼部分'{script}' 的結(jié)構(gòu):

  • 基礎(chǔ)結(jié)構(gòu): '{script}'

  • 匹配結(jié)構(gòu):' /pattern/{script}'

(兩個//之間做匹配脯颜,匹配上的行就做代碼里面的處理,匹配不上就不做處理)

  • 擴(kuò)展結(jié)構(gòu):BEGIN {script} {script} END {script}

(分三段:第一段BEGIN {script}做代碼里的定義贩据,第二段{script}做第二件事情栋操,第三段END {script}做最后的處理)

awk在讀取一行文本時,會用預(yù)定義的字段分隔符劃分每個數(shù)據(jù)字段(分成很多列)饱亮,并分配給一個變量矾芙。

  • $0:代表整個文本行(所有列)
  • $1:代表文本行中的第1個數(shù)據(jù)字段(第1列)近上;
  • ……:$2...
  • $NF:代表文本行中的最后一個數(shù)據(jù)字段(代表每一行的最后一列)

awk默認(rèn)的字段分隔符是任意空白字符(如:空格 or制表符)剔宪,awk識別到空格or 制表符都切割,二選一可以用-F參數(shù)自定義分隔符,-F ' ' 或是-F '\t '葱绒。

awk基礎(chǔ)結(jié)構(gòu)

cut命令與awk命令分別切割example.gtf文件的第9列對比:

用cut命令切割第9列對比:

less -S Data/example.gtf | cut -f 9 |less -S
##cut默認(rèn)的分隔符是\t感帅,所以空格不會切掉
cut命令切割對比

awk命令切割第9列:

less -S Data/example.gtf | awk '{print $9}' |less -S
##與cut命令切割的結(jié)果不一樣, awk識別空格為分隔符哈街。awk命令處理的特點留瞳,默認(rèn)有多個分割符拒迅。
awk命令切割第9列

example.gtf里第9列的內(nèi)容:attributes:
屬性骚秦,必須要有以下兩個值:

gene_id value: 表示坐標(biāo)在基因組上的基因座的唯一的ID gene_id 與 value 值用空格分開,如果值為空璧微,則表示沒 有對應(yīng)的基因作箍。
transcript_id value: 預(yù)測的轉(zhuǎn)錄本的唯一ID。 transcript_id與value值用空格分開前硫,空表示沒有轉(zhuǎn)錄本胞得。

指定分割第9列和第10列

less -S Data/example.gtf | awk '{print $9,$10}' |less -S
分割第9和第10列

要想把第9列完完整打印出來,需要指定制表符\t為分割符

less -S Data/example.gtf | awk -F '\t' '{print $9}' |less -S
###awk命令指定制表符\t為分割符,空格不再是分割符屹电,沒有被切掉阶剑,所有的內(nèi)容都是第9列
awk命令指定制表符\t為分割符

awk匹配結(jié)構(gòu):兩個斜杠//

less -S Data/example.gtf | awk -F '\t' '/UTR/{print $0}' |less -S
##首先搜索UTR,再對所在的行進(jìn)行處理后打印出來危号,$0表示一整行
##$0表示一整行牧愁,包含多個字段(多列),如果要對第1列外莲,第4列猪半,第5列進(jìn)行操作。
 less -S Data/example.gtf | awk -F '\t' '/UTR/{print $1,$4,$5}' |less -S
##awk匹配/UTR/與grep UTR有類似的匹配功能偷线,不過awk的后面命令可以做各種各樣的操作磨确。
awk命令匹配用法

awk擴(kuò)展結(jié)構(gòu):三段式

 less -S Data/example.gtf | awk 'BEGIIN{print "find UTR feature"} /UTR/{print $0} END{ print "end"}'| less -S
##第一段:BEGIIN{print "find UTR feature"},熱身部分的代碼声邦,不對文件的行起作用乏奥,也就是說awk命令在處理第一行之前先執(zhí)行BEGIN里的代碼,先熱身亥曹。
##第二段:UTR/{print $0}對每一行起作用:先搜索UTR英融,如果有就打印$0這一行出來,如果沒有UTR就什么都不做歇式,處理第一行到最后一行都是這句代碼驶悟。
##第三段:END{ print "end"}在上一步執(zhí)行完所有的行之后再打印end這個單詞
##BEGIN和END可以用正則表達(dá)式,但是用得比較少

awk先對一行處理材失,再分隔成多列痕鳍,再對列進(jìn)行處理,在處理過程中就看不到內(nèi)在的變化

awk內(nèi)置變量

awk在處理時,有些變量是看不見的笼呆,內(nèi)置變量:

  • FS:定義輸入字段分隔符熊响,F(xiàn)ieldSeparator,同–F
    FS是一個變量诗赌,-F是一個參數(shù)汗茄,所處的位置不一樣。

  • RS:定義輸入記錄分隔符铭若,Record Separator
    怎么識別一行一行洪碳,awk識別一個換行符,一條記錄就是一行叼屠,每行最后有一個換行符瞳腌,可以定義句號為分 割符,然后進(jìn)行一些操作镜雨,把首字母變成大寫嫂侍。

  • OFS:定義輸出字段分隔符,Out FieldSeparator
    輸入是\t為分隔符荚坞,可以以空格符作為輸出挑宠,輸出列與列之間是空格符。

  • ORS:定義輸出記錄分隔符颓影,Out Record Separator
    比如每一句以換行符輸出各淀。

  • NF:數(shù)據(jù)文件中的字段總數(shù),可以簡單理解為列數(shù)
    記錄多少列瞭空,處理第幾列時揪阿,NF為第幾列,處理文件時一直變咆畏。

  • NR:已處理的輸入記錄數(shù)南捂,可以簡單理解為行數(shù)
    記錄多少行,處理第幾行時旧找,NR為第幾行溺健。

  • 也可以通過-v參數(shù)自定義變量或傳遞外部變量

內(nèi)置變量用得比較少,因為大多數(shù)生信文件是比較規(guī)整的钮蛛,但不排除會遇到奇奇怪怪的文件鞭缭。

awk內(nèi)置變量常見用法

通過定義分隔,空格不讓切

##首先把第9列的東西打印出來
less -S Data/example.gtf | awk '{print $9}' |less -S
image.png
##FS="\t"定義分隔符魏颓,定義列的分隔符岭辣。
less -S Data/example.gtf | awk 'BEGIN{FS="\t"} {print $9}' |less -S
##FS="\t"定義制表符\t為列與列之間的分隔符,把所有的東西都打印出來甸饱,空格不再是一個分隔符沦童,
image.png
##加NR仑濒,理解為行數(shù)
less -S Data/example.gtf | awk 'BEGIN{FS="\t"} {print NR $9}' |less -S
##NR,記錄分隔符偷遗,就是記錄行墩瞳,比如處理第一行是,NR為1氏豌,喉酌,處理第3行,NR就為3.如行前面的數(shù)字泵喘。
加NR統(tǒng)計行

以后需要用到內(nèi)置變量時泪电,通過幾個例子去探索它的具體用法

awk條件和循環(huán)語句

awk本身是一門編程語言,編程語言本來就有循環(huán)語句

if:條件判斷

awk ' { if (判斷條件) {yes} else {no} } '

與R語言里的判斷語句是一模一樣的

for:循環(huán)語句

awk ' { for (循環(huán)條件) {循環(huán)語句} } '

經(jīng)常出現(xiàn)的問題:

  • 1.引號涣旨,括號歪架,花括號不成對股冗;

  • 2.在外面只能用單引號霹陡,在里面用雙引號,不能亂用引號止状。

  • 注意細(xì)節(jié):

    一般把引號烹棉,括號,大括號成對輸入(寫)怯疤,避免漏掉一個浆洗。

if語句的簡單用法

less -S Data/example.gtf | awk '{if($3=="gene") print $0}' |less -S
##如果$3=="gene"就打印$0,如果$3不等于gene,就什么都不用做集峦。
##==表示判斷
awk條件循環(huán)語句的應(yīng)用

awk結(jié)合else的使用

如果條件成立就做一件事情伏社,如果條件不成立(else),就做另一件事情塔淤。

less -S Data/example.gtf | awk '{if($3=="gene") {print $0} else{print $3 " is not gene "}}' | less -S
##打印$3,$3后面接了字符串
awk條件循環(huán)語句加上else的應(yīng)用
less -S Data/example.gtf | awk '{if($3=="gene") {print $1,$2,$3}}' | less -S
##奇怪的現(xiàn)象:輸出發(fā)現(xiàn)第一列和第二列之間不是制表符摘昌,是空格符。awk處理有時候輸入為制表符高蜂,輸出就以空格為分割符聪黎。在'{if($3=="gene") 加入BEGIN=OFS,定義輸出分隔符為制表符就不會出現(xiàn)以上的情況备恤。
輸入為制表符稿饰,輸出為空格

awk里面的for循環(huán)

可能和R語言里的for循環(huán)不一樣

less -S Data/example.gtf | awk '{for(i=1;i<4;i++){print $i}}' | less -S
##i=i;i<4;i++露泊,有C語言基礎(chǔ)就比較容易理解喉镰,  
##i=1,小于4惭笑,執(zhí)行第一行第一列侣姆,i++就是等于2,可以執(zhí)行第二行、第二列铺敌,i+1=3(i=ii+1.
##i=4,不再小于4汇歹,就不再執(zhí)行。
#第1行偿凭,執(zhí)行1,2,3列
#第2行产弹,執(zhí)行1,2,3列
##累加到條件不成立就退出
##輸出的結(jié)果是$1,$2,$3,一列占了一行。
image.png
##傳遞給命令paste - - -弯囊,每三行合并成每三列
less -S Data/example.gtf | awk '{for(i=1;i<4;i++){print $i}}' | less -S | paste - - -
傳遞給paste命令-每三行變?nèi)?/div>

awk的數(shù)學(xué)運算

+(加)痰哨,- (減), * (乘)匾嘱,/ (除)
^ (冪) 斤斧,** (平方), % (取余)
int(x) x的整數(shù)部分霎烙,取靠近零一側(cè)的值
log(x) x的自然對數(shù)

先了解撬讽,不要求立馬掌握,后面多練習(xí)

減法運算示例

#用第5列減去第4列悬垃,其實就是求外顯子的長度
less -S Data/example.gtf | awk '/exon/ {print $5-$4}' | less -S
##首先要匹配到外顯子exon游昼,再求外顯子的長度
awk減法運算

除法運算示例

less -S Data/example.gtf | awk '/exon/ {print $5/$4}' | less -S
##$5/$4沒有實際意義,為了演示尝蠕。除法默認(rèn)保留5位小數(shù)烘豌,如果要做其它運算,用/把$5-$4里的-替代掉看彼,
image.png

運算取整

##用int()取整數(shù)
 less -S Data/example.gtf | awk '/exon/ {print int($5/$4)}' | less -S
 ##上面的一行代碼中$5/$4沒有任何意義廊佩,只是為了演示,拿來用靖榕。
 #可以不用匹配外顯子
 less -S Data/example.gtf | awk '{print int($5/$4)}' | less -S
image.png

四舍五入

 less -S Data/example.gtf | awk '{print $5/$4}' | less -S
 ###先運行原來的
less -S Data/example.gtf | awk '{print int($5/$4+0.5)}' | less -S
 ##四舍五入的運算

作業(yè)題

1.任意挑4句前面的命令自己動手敲一遍

##1.1打印example.gtf的第9列
less -S Data/example.gtf | awk '{print $9}' | less -S

##1.2定義分隔符為制表符
less -S Data/example.gtf | awk -F '\t' '{print $9}' | less -S

##1.3匹配UTR的行
 less -S Data/example.gtf | awk '/UTR/{print $0}' | less -S

##1.4
 less -s Data/example.gtf | awk 'BEGIN{print "find UTR feature"}/UTR/{print $0} END{print "end"}' | less -S
 ###一定要注意單引號标锄,雙引號,小括號序矩,花括號的成對

2.使用head查看example.gtf文件

head Data/example.gtf

3.將2結(jié)果傳遞給awk鸯绿,輸出含有ENSEMBL的行

##第一種做法,用匹配關(guān)鍵詞
head Data/example.gtf | awk '/ENSEMBL/{print $0}' | less -S
##第二種做法簸淀,用if語句
less -S Data/example.gtf | awk '{if($2=="ENSEMBL") print $0}' | less -S
##因為處理的是列瓶蝴,定義分隔符為制表符
less -S Data/example.gtf | awk 'BEGIN{FS="\t"} {if($2=="ENSEMBL") print $0}' | less -S

4.結(jié)合所學(xué),輸出以下結(jié)果:

作業(yè)題--要求輸出這樣的結(jié)果
#可以用cut命令把第9列切出來
head  Data/example.gtf | cut -f 9
#用awk命令把第9列打印出來
head  Data/example.gtf | awk '{print $9}'
#定義分隔符
head  Data/example.gtf | awk -F '\t' '{print $9}'
##第9類列的所有東西都被打印出來了租幕。
##第2舷手,第4,第6是我們想要的結(jié)果(我之前的思路錯了)
 head  Data/example.gtf | awk -F '\t' '{print $9}' | awk '{print $2,$4,$6}'
##兩個awk命令一起用
初步拿到我們想要的三列
##最后需要把“”和劲绪;去掉
##我們之前沒有學(xué)過刪除字符男窟,用sed命令的替換
head  Data/example.gtf | awk -F '\t' '{print $9}' | awk '{print $2,$4,$6}' | sed -e 's/"http://' -e 's/;//'
##只替換第一處的“和盆赤;
sed命令默認(rèn)只替換第一處
##sed命令替換時,只默認(rèn)替換第一處歉眷,加g牺六,實現(xiàn)全局替換
head  Data/example.gtf | awk -F '\t' '{print $9}' | awk '{print $2,$4,$6}' | sed -e 's/"http://g' -e 's/;//g'
sed命令加g實現(xiàn)全局替換

小郭老師很耐心一步步的講解,方便理解汗捡。

根據(jù)老師的提示淑际,自己嘗試其它做法:

less -S Data/example.gtf
##先查看圖中的三列信息是在example.gtf里的第幾列,發(fā)現(xiàn)需要提取的信息在分別在10,12,14列
head  Data/example.gtf | awk -F '\t' '{print $10,$12,$14}'
###需要注意觀察$10,$12,$14之間不是通過\t分隔的扇住,
head  Data/example.gtf | awk -F '' '{print $10,$12,$14}'
##換成空格為分隔符春缕,但是結(jié)果錯,空格不是空白艘蹋,單引號里要加空格
head  Data/example.gtf | awk -F ' ' '{print $10,$12,$14}'
##其實awk默認(rèn)分隔符為空格锄贼,不用-F參數(shù)
head  Data/example.gtf | awk '{print $10,$12,$14}'
一步步探索第4題

最后的步驟和小郭老師的一樣

##用sed的命令替換,字符串的雙引號女阀,以及宅荤;分隔符,只用到一個awk命令
 head  Data/example.gtf | awk '{print $10,$12,$14}' | sed -e 's/"http://g' -e 's/;//g'
引號和分隔符的替換

說明:

以上內(nèi)容主要是跟著生信技能樹的教學(xué)視頻和課件內(nèi)容學(xué)習(xí)做的筆記强品,小郭老師講得很詳細(xì)膘侮,舉一反三屈糊,方便記憶和理解的榛。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市逻锐,隨后出現(xiàn)的幾起案子夫晌,更是在濱河造成了極大的恐慌,老刑警劉巖昧诱,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晓淀,死亡現(xiàn)場離奇詭異,居然都是意外死亡盏档,警方通過查閱死者的電腦和手機(jī)凶掰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蜈亩,“玉大人懦窘,你說我怎么就攤上這事≈膳洌” “怎么了畅涂?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長道川。 經(jīng)常有香客問我午衰,道長立宜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任臊岸,我火速辦了婚禮橙数,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘帅戒。我一直安慰自己商模,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布蜘澜。 她就那樣靜靜地躺著施流,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鄙信。 梳的紋絲不亂的頭發(fā)上瞪醋,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天,我揣著相機(jī)與錄音装诡,去河邊找鬼银受。 笑死,一個胖子當(dāng)著我的面吹牛鸦采,可吹牛的內(nèi)容都是我干的宾巍。 我是一名探鬼主播,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼渔伯,長吁一口氣:“原來是場噩夢啊……” “哼顶霞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起锣吼,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤选浑,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后玄叠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體古徒,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年读恃,在試婚紗的時候發(fā)現(xiàn)自己被綠了隧膘。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,861評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡寺惫,死狀恐怖疹吃,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情肌蜻,我是刑警寧澤互墓,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站蒋搜,受9級特大地震影響篡撵,放射性物質(zhì)發(fā)生泄漏判莉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一育谬、第九天 我趴在偏房一處隱蔽的房頂上張望券盅。 院中可真熱鬧,春花似錦膛檀、人聲如沸锰镀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽泳炉。三九已至,卻和暖如春嚎杨,著一層夾襖步出監(jiān)牢的瞬間花鹅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工枫浙, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留刨肃,地道東北人。 一個月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓箩帚,卻偏偏與公主長得像真友,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子紧帕,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,860評論 2 361

推薦閱讀更多精彩內(nèi)容