Code
之前一直用vlookup
做垂直查找,直到后來接觸了測序數(shù)據(jù)...動輒一個excel幾十兆灰粮,丐版的MBPvlookup
經(jīng)常就卡死了忍坷;后來用R的left_join,但還是感覺不方便佩研,先要讀進去,還要保證colname一致...最后忍不了了嘉抒,直接一頓尋找袍暴,找到了用awk直接對倆文件進行vlookup。
代碼如下:
shawnwx@bogon tep$ awk 'NR==FNR{a[$1]=$0;next}NR>FNR{if($1 in a)print $0"\t"a[$1]}' file_query file_source >output.xls
可以寫成awk script然后alias重命名岗宣,當(dāng)然也可以添加到環(huán)境變量淋样。
# 新建一個awk script
vim vlookup.awk
# 按I進入編輯模式,把下面代碼粘貼進去趁猴。然后按ESC,按: wq.
NR==FNR{a[$1]=$0;next}NR>FNR{if($1 in a)print $0"\t"a[$1]}
# 重命名成一個簡短的vlkup
alias vlkup="awk -f vlookup.awk"
# 現(xiàn)在就可以直接使用vlkup
vlkup file_query file_source > output.xls
# 寫入環(huán)境變量(mac),一般會把常用的腳本放到一個專門的路徑下娱挨,比如我的在~/aliascode
open ~/.bash_profile
# 將下面代碼寫入保存
alias vlkup="awk -f ~/aliascode/vlookup.awk"
source ~/.bash_profile
# =====================done======================
解讀
在awk里捕犬,NR和FNR的含義相近,唯一的區(qū)別就是作用范圍柴钻,NR是所有讀取的行信息計數(shù)垢粮,而FNR是正在讀取文件的行信息技術(shù),F(xiàn)NR在文件切換時會從0重新開始計數(shù)蜡吧,所以上述語句的意思是:
NR==FNR在判斷是不是在讀a.txt,如果是a.txt則以第一個數(shù)據(jù)項為key绍些,以整行信息為數(shù)據(jù)組成數(shù)組耀鸦;
NR>FNR則判斷是不是在讀b.txt,因為此時NR=(a.txt的總行數(shù)+FNR)氮帐,如果是洛姑,則判斷第一個數(shù)據(jù)項在不在a.txt數(shù)據(jù)組成的數(shù)組里,如果在楞艾,則打印本行加數(shù)組項龄广。
例子:
o@t /tmp $ cat a.txt
1 abc
2 def
3 ghi
4 jlm
o@t /tmp $ cat b.txt
3 shit
1 rubb
o@t /tmp $ awk 'NR==FNR{a[$1]=$0;next}NR>FNR{if($1 in a)print $0"\n"a[$1]}' a.txt b.txt
3 shit
Reference:
補充
當(dāng)時用這個時候最后還返回了A的择同?第一列净宵,其實沒有這個必要,最后改了一下
NR==FNR{a[$1]=$0;next}NR>FNR{if($1 in a)print $0}
直接print出找到的择葡。因為有一次出來居然換行了,我這里是Tab分割的阻星,也木有用換行符呀虹曙。看來還是要深入學(xué)習(xí)一下
March 7, 2019補充
今天要合數(shù)據(jù)酝碳,想著批量做vlk疏哗,但發(fā)現(xiàn)之前寫的這個并不合適,因為之前只返回找到的值返奉,對沒有匹配的值實際上想返回NA所以重新寫了如下:
NR==FNR{a[$1]=$0;next}NR>FNR{if($1 in a)print a[$0]; else print $1"\t""NA""\t""NA""\t""NA"}
# 前面如何判斷就不說了,就說后面返回雷逆,$1在a里面污尉,則打印a這一樣,如果不在則返回$1\tNA\tNA\tNA 使用方法還是和之前一樣
# awk -f vlkupV1.awk data.file ID.file >output.file,然后又做了個叫vlk的快捷命令
alias vlk="awk -f ~/aliascode/vlkupV1.awk"
vim ~/.bashrc
# vlookup for return in "NA" for "else" condition
alias vlk="awk -f ~/aliascode/vlkupV1.awk"
:wq
后面應(yīng)該還會有補充....不斷完善匯中慢慢學(xué)習(xí)..