前言
??對(duì)于用Linux來處理數(shù)據(jù)的用戶來說吃警,應(yīng)該都知道Linux處理數(shù)據(jù)的三個(gè)強(qiáng)有力的命令awk冠胯、sed拄氯、grep——人稱三劍客躲查。那么今天想跟大家分享一個(gè)其中的一個(gè)命令awk,為什么要跟大家分享這個(gè)命令呢译柏?因?yàn)橛袝r(shí)候我們需要做的事情很簡(jiǎn)單镣煮,不知道去寫一個(gè)腳本,那就可以用一行命令來解決鄙麦。awk用來干這些事情可以說是非常適合典唇,因?yàn)閍wk可以做很多事情如匹配镊折、切割、轉(zhuǎn)置介衔,甚至還可以在其內(nèi)部寫循環(huán)恨胚,用的好的話可以提高工作效率。今天我們來說一下三種常見情形下炎咖,如何方便快速的用awk一行代碼來解決赃泡。
??下面我們來簡(jiǎn)單介紹一下awk的語法,完整的語法為:awk [optional] 'BEGIN{...}{...}END{...}' file/stdin乘盼。awk可用直接讀取文件的內(nèi)容也可以接受來至標(biāo)準(zhǔn)輸入的內(nèi)容升熊,有了這個(gè)特性結(jié)合管道“|”來使用更加方便。在命令行可以查看awk可以接受的全部選項(xiàng)(如下所示)蹦肴,其實(shí)大部分我也沒用過僚碎,感興趣可以自己摸索一番,最常用的兩個(gè)選項(xiàng)就是-F阴幌、-v勺阐,-F后面接的參數(shù)是用來分割內(nèi)容的分隔符,-v 后面接的參數(shù)是awk外部的一個(gè)變量矛双。
awk --help
Usage: awk [POSIX or GNU style options] -f progfile [--] file ...
Usage: awk [POSIX or GNU style options] [--] 'program' file ...
POSIX options: GNU long options: (standard)
-f progfile --file=progfile
-F fs --field-separator=fs
-v var=val --assign=var=val
Short options: GNU long options: (extensions)
-b --characters-as-bytes
-c --traditional
-C --copyright
-d[file] --dump-variables[=file]
-e 'program-text' --source='program-text'
-E file --exec=file
-g --gen-pot
-h --help
-L [fatal] --lint[=fatal]
-n --non-decimal-data
-N --use-lc-numeric
-O --optimize
-p[file] --profile[=file]
-P --posix
-r --re-interval
-S --sandbox
-t --lint-old
-V --version
1渊抽、獲取想要的列
??下面我們來通過具體的場(chǎng)景展現(xiàn)awk的能力,首先來看一下如何使用awk來分割內(nèi)容獲取想要的部分议忽。例如這里有個(gè)文件總共9列懒闷,分隔符為制表符,但值得注意是第一列的內(nèi)容為Ensembl ID和Symbol ID兩部分組成栈幸,其中分隔符為空格愤估,內(nèi)容如下所示:
gene C293T igf Igf2bp2 InputI InputP ptbp Ptbp1 S293T
ENSG00000000003.15 TSPAN6 4.893 6.088 5.516 5.033 4.853 5.391 5.705 4.862
ENSG00000000005.6 TNMD 0.343 0 0 0.3872 0.3346 0 0 0.6902
ENSG00000000419.12 DPM1 4.529 4.691 4.685 4.554 4.375 2.234 4.394 4.372
ENSG00000000457.14 SCYL3 1.841 2.571 3.002 2.176 2.011 1.565 2.255 1.879
ENSG00000000460.17 C1orf112 3.431 4.441 4.324 3.674 3.618 2.611 3.857 3.652
ENSG00000000938.13 FGR 0 0 0 0 0.02306 0.07593 0 0
ENSG00000000971.16 CFH 0.1248 0.3185 0.01851 0.1209 0.1302 0.1272 0.006274 0.1486
ENSG00000001036.14 FUCA2 4.774 5.482 5.887 4.805 4.812 4.35 5.494 4.785
ENSG00000001084.13 GCLC 4.393 3.463 5.523 4.408 4.586 2.699 4.827 4.571
ENSG00000001167.14 NFYA 4.127 4.392 5.601 4.247 4.233 2.392 4.011 4.084
ENSG00000001460.18 STPG1 3.958 4.261 4.496 3.924 3.947 2.158 3.547 3.925
那我們來看如何提取想要的列,示例代碼如下:
#提取前三列的內(nèi)容到新文件里
awk -F"\t" '{OFS="\t";print$1,$2,$3}' zhaoy_log2TPM.txt >new.txt
#因?yàn)檩斎牒洼敵龅姆指舴恢滤僦罚厦娴拿钸€可以寫成
awk '{OFS=FS="\t";print$1,$2,$3}' zhaoy_log2TPM.txt >new.txt
#查看新文件內(nèi)容
head nex.txt
gene C293T igf
ENSG00000000003.15 TSPAN6 4.893 6.088
ENSG00000000005.6 TNMD 0.343 0
ENSG00000000419.12 DPM1 4.529 4.691
ENSG00000000457.14 SCYL3 1.841 2.571
ENSG00000000460.17 C1orf112 3.431 4.441
??你以為這樣就結(jié)束了么玩焰,awk還可以更厲害一點(diǎn),還拿上面文件來說芍锚,我現(xiàn)在還是要前3列昔园,但是第一列我只要Ensembl ID,那么該如何實(shí)現(xiàn)呢并炮?請(qǐng)看下面示例代碼:
#以制表符和空格一起作為分割符來分割內(nèi)容
awk -F "[\t ]" 'BEGIN{print"gene\tC293T\tigf"}{OFS="\t";if(NR>1)print$1,$3,$4}' zhaoy_log2TPM.txt >new.txt
#查看內(nèi)容
gene C293T igf
ENSG00000000003.15 4.893 6.088
ENSG00000000005.6 0.343 0
ENSG00000000419.12 4.529 4.691
ENSG00000000457.14 1.841 2.571
ENSG00000000460.17 3.431 4.441
ENSG00000000938.13 0 0
ENSG00000000971.16 0.1248 0.3185
ENSG00000001036.14 4.774 5.482
ENSG00000001084.13 4.393 3.463
??是不是很方便默刚,awk可以同時(shí)接受多個(gè)分隔符,這個(gè)功能就更厲害了逃魄,即使用來處理gtf文件也是可以的荤西。用好了可以一行命令解決大部分的文件。
2、兩個(gè)文件匹配
??有時(shí)候我們想要根據(jù)兩個(gè)文件共有列的內(nèi)容來合并兩個(gè)文件皂冰,這個(gè)適合如何用一行代碼來完成呢?例如我有兩個(gè)文件內(nèi)容如下:
#文件test1.txt
gene C293T igf
ENSG00000000003.15 4.893 6.088
ENSG00000000005.6 0.343 0
ENSG00000000419.12 4.529 4.691
ENSG00000000457.14 1.841 2.571
ENSG00000000460.17 3.431 4.441
#文件test2.txt
gene Igf2bp2 Igf2bp2
ENSG00000000003.15 5.516 5.033
ENSG00000000005.6 0 0.3872
ENSG00000000419.12 4.685 4.554
ENSG00000000457.14 3.002 2.176
ENSG00000000460.17 4.324 3.674
??可以看到上面兩個(gè)文件有共同的列店展,那么我們?nèi)绾胃鶕?jù)這個(gè)共同的列來匹配合并兩個(gè)文件呢?請(qǐng)看下面的代碼:
#根據(jù)第一列來合并兩個(gè)文件
awk 'NR==FNR{OFS=FS="\t";a[$1]=$2FS$3;next}{if($1 in a)print$0,a[$1]}' test1.txt test2.txt >merge.txt
#查看合并的內(nèi)容
gene Igf2bp2 InputI C293T igf
ENSG00000000003.15 5.516 5.033 4.893 6.088
ENSG00000000005.6 0 0.3872 0.343 0
ENSG00000000419.12 4.685 4.554 4.529 4.691
ENSG00000000457.14 3.002 2.176 1.841 2.571
ENSG00000000460.17 4.324 3.674 3.431 4.441
ENSG00000000938.13 0 0 0 0
是不是很方便秃流,有了這個(gè)功能赂蕴,提取匹配兩個(gè)文件來提取內(nèi)容,只用一行代碼就可以搞定舶胀,分分鐘的事概说!
3、文件轉(zhuǎn)置
??有時(shí)候需要將文件行和列轉(zhuǎn)置嚣伐,這個(gè)時(shí)候也可以用awk來完成糖赔,同樣是一行代碼即可搞定。就拿上面的test1.txt文件來做示范轩端,示例代碼如下:
#轉(zhuǎn)置文件
awk '{for(i=1;i<=NF;i++){a[FNR,i]=$i}}END{for(i=1;i<=NF;i++){for(j=1;j<=FNR;j++){printf a[j,i]"\t"}print ""}}' test1.txt >zhuanzhi.txt
#查看轉(zhuǎn)置后的文件
gene ENSG00000000003.15 ENSG00000000005.6 ENSG00000000419.12 ENSG00000000457.14
C293T 4.893 0.343 4.529 1.841
igf 6.088 0 4.691 2.571
??轉(zhuǎn)置文件用awk來做也是分分鐘的事放典,用awk來處理數(shù)據(jù)有時(shí)候真的是省時(shí)省力,現(xiàn)在是不是覺得awk很給力基茵,其實(shí)它還有很多功能奋构,學(xué)好了可以用來做很多的事。對(duì)于沒有編寫腳本需求的事來說拱层,用awk命令行來解決弥臼,一行代碼方便快捷。
最后
??emm根灯,今天就分享到這里径缅,現(xiàn)在是不是覺得awk這個(gè)命令很實(shí)用,趕快用起來吧烙肺!