不要輕易嘗試用wc -l統(tǒng)計(jì)Windows系統(tǒng)出產(chǎn)文件的滋味

????不知不覺又鴿了這么久,嗨呀真是毫無愧疚感~連天數(shù)都懶得統(tǒng)計(jì)了呢!
????昨天在做文件拆分時(shí)遇到了一個(gè)大坑,想想一定要記下來,以防以后我或者跟我遇到一樣問題的小伙伴再掉進(jìn)去?!静幌矎U話小伙伴請(qǐng)直接跳到結(jié)論】


????事情其實(shí)很簡(jiǎn)單,我有一個(gè)總文件all.genelist,里面包含了三個(gè)物種的所有注釋出來的基因家族對(duì)應(yīng)的轉(zhuǎn)錄本號(hào),在做分組注釋時(shí)為了提高效率,我決定把三個(gè)物種的轉(zhuǎn)錄本號(hào)分別拆出來,也就是:A.genelistB.genelist、C.genelist。
????總文件大概長(zhǎng)這樣:

#all.genelist
Gene1   A_trans000001
Gene2   A_trans000002
...
GeneN   A_trans[0-9]{6}
Gene1   B_trans000001
Gene2   B_trans000002
...
GeneN   B_trans[0-9]{6}
Gene1   C_trans000001
Gene2   C_trans000002
...
GeneN   C_trans[0-9]{6}

????當(dāng)然,真實(shí)的對(duì)應(yīng)關(guān)系沒有這么整齊,我恨不得它整齊一點(diǎn)。
????不過因?yàn)槲锓N的轉(zhuǎn)錄本號(hào)前綴不一樣,使用grep很輕松就將它們分開了。

$ grep 'A_trans' all.genelist > A.genelist

????沒錯(cuò),就是這么簡(jiǎn)單粗暴,由于過于簡(jiǎn)單粗暴,qiang細(xì)po心zheng的我手賤地檢查了一下輸入和輸出文件的行數(shù),結(jié)果粗大事了!
????當(dāng)時(shí)的情況是這樣的:

$ wc -l ./*.genelist
326973  all.genelist
115305  A.genelist
107285  B.genelist
104384  C.genelist

????如果我那不及格的高數(shù)水平夠用的話,A.genelist、B.genelist、C.genelist三個(gè)輸出文件的行數(shù)總和應(yīng)該是326974,比all.genelist的行數(shù)326973多了一行,這是為什么呢?原文件里應(yīng)該是只包含這三個(gè)物種的信息啊,再也沒有多余的行了。
????我的第一反應(yīng)是 grep命令太過簡(jiǎn)單粗暴,拆分過程出了什么錯(cuò),于是嘗試用awk指令又重新拆了一遍。

$ awk '$2~/^A_trans[0-9]{6}$/{print $0}' all.genelist > A.genelist

????可是結(jié)果是一樣的,在wc -l后原文件依然比三個(gè)輸出文件行數(shù)總和少一行,不死心的我又用sed的正則對(duì)結(jié)果進(jìn)行檢查,看是否有兩行連在了一起被分在了一起。

$ awk '{print $2}' all.genelist | sed 's/_trans[0-9]\{6\}//g' | sort | uniq
A
B
C

????輸出結(jié)果證明我的第二列都是整齊的,第一列同理檢查也是整齊的,那么問題來了,多出來的一行究竟在哪里呢?
????我向師兄求助,師兄拋出行數(shù)出問題萬金油大法:刪除空行。
????不對(duì)啊,是輸出文件行數(shù)多了,刪除什么空行?但我還是抱著試試看的態(tài)度去刪了一下原文件的空行。因?yàn)檫@個(gè)文件是從Windows系統(tǒng)出品,雖然用dos2unix處理過,心里還是不踏實(shí)——結(jié)果,奇怪的事發(fā)生了。

$ grep -v '^$' all.genelist > all.filtered.genelist
$ wc -l *.genelist
326973  all.genelist
326974  all.filtered.genelist
115305  A.genelist
107285  B.genelist
104384  C.genelist

????看到這個(gè)統(tǒng)計(jì)結(jié)果時(shí),我整個(gè)人都凌亂了。明明執(zhí)行的是刪除空行操作,怎么輸出的文件比原文件還多了一行?從邏輯上完全說不通。
????不過,這樣看來,問題倒是解決了,原來是原文件少統(tǒng)計(jì)了一行,我回到Windows系統(tǒng)用Excel打開,確認(rèn)之前是統(tǒng)計(jì)出錯(cuò)了??墒菫槭裁唇y(tǒng)計(jì)會(huì)出錯(cuò)?我又寄希望于師兄。
????師兄:難道你也是處女座?
????也?等等,師兄是不是暴露了什么……


????不開玩笑了,最后經(jīng)過我多方查證,本以為是dos2unix的問題,它在轉(zhuǎn)換格式的過程中做了什么不可描述的事,沒想到是wc -l的鍋,它只以\n作為行結(jié)束符統(tǒng)計(jì)行數(shù),所以最后一行如果沒有\n的話會(huì)統(tǒng)計(jì)丟失。
????Windows系統(tǒng)產(chǎn)生的文件末尾經(jīng)常無\n,而是直接用了文件結(jié)束符EOF。這樣文件使用Linux平臺(tái)的wc統(tǒng)計(jì)就會(huì)少一行,這個(gè)問題不論用管道符還是dos2unix都無法解決。只有用vi編輯器或grep一類行處理命令會(huì)自動(dòng)給它加上\n,所以以后,不要輕易嘗試用wc -l統(tǒng)計(jì)Windows系統(tǒng)出產(chǎn)文件的滋味!
????但對(duì)于正在學(xué)習(xí)期的我來說,這樣的錯(cuò)誤能夠一次性鍛煉文本處理三劍客的正則表達(dá)式,還是挺值得的,就是有點(diǎn)耽誤課題進(jìn)度。

最后,想給Windows這個(gè)BUG虐我千萬遍的小婊砸發(fā)一個(gè)表情包

參考資料:https://blog.csdn.net/longshenlmj/article/details/42707919

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容