Linux中的文件內(nèi)查找小技巧

寫在前面的廢話

這一周我為自己的馬虎付出了嚴(yán)重的代價(jià)Q锸妗!!
每天十幾個(gè)小時(shí)一直在debug……以后寫代碼之前一定要拜拜雍正宝恶,專治八阿哥(bug)


image.png

雖然debug讓我無心其他事情,但是咱說好的周更不能斷(其實(shí)是我找到了bug乘综,想寫篇文章壓壓驚)

太長不看系列

  • 最粗魯?shù)霓k法:grep -f (慢憎账,內(nèi)存需求太大)
  • 比較省事的辦法:R的merge函數(shù) (較快,但是內(nèi)存需求賊大)
  • 比較機(jī)智的辦法:字典/哈希(很快卡辰,Python里面叫作字典鼠哥,Perl里面似乎叫作哈希熟菲,對于不會(huì)這兩門語言的同學(xué)友好性太差)
  • 穩(wěn)如老狗的辦法:awk命令 (也是依賴字典方法,速度快朴恳,操作簡單抄罕,深得吾心)


    image.png

廢話超多系列

我相信你們和我一樣,有時(shí)需要知道文件A中有哪些行出現(xiàn)在文件B中于颖。說起來有點(diǎn)繞呆贿,直接舉個(gè)例子可能會(huì)更通俗易懂一些:

> cat A.txt
Hello
Thank you
Thank you very much
> cat B.txt
Hello
Welcome to
Beijing

文件A中有哪些行在文件B中也出現(xiàn)過,這個(gè)例子比較簡單森渐,我們直接就能看出A.txt中的Hello在B.txt文件中出現(xiàn)做入。

但是當(dāng)文件較大時(shí)怎么辦呢?一百行的話同衣,你也許還可以試試 肉眼去觀察竟块,一旦行數(shù)上萬,就必須借助計(jì)算機(jī)幫助我們完成這些事情了

不瞞你說耐齐,我之前查找的兩個(gè)文件浪秘,一個(gè)幾百萬行,另一個(gè)上千萬行埠况,為了找一個(gè)合適的方法可是苦惱了很久

最粗魯?shù)霓k法:grep

grep方法比較粗魯耸携,但針對比較小的文件,我還是很喜歡用它的辕翰。因?yàn)樗恍枰昧鶄€(gè)字符夺衍,真的節(jié)省體力。
cat -f A.txt B.txt : 可以把B文件中存在于A文件中的行輸出喜命,具體操作如下

image.png

如果你使用了-v參數(shù)沟沙,則可以進(jìn)行另一個(gè)騷操作,輸出只存在與B文件而不存在與A文件中的行壁榕。但是這個(gè)方法有一些缺點(diǎn)尝胆,比如:

  • 不能分字段查找(比如A文件的第二列信息,是否在B文件中的第三列信息中出現(xiàn))
  • 針對大文件护桦,耗時(shí)長且內(nèi)存消耗大(時(shí)間我沒有專門統(tǒng)計(jì)過含衔,但是在運(yùn)行這個(gè)命令的時(shí)候內(nèi)存倒是溢出過,如下圖)


    image.png

比較省事的辦法:R的merge函數(shù)

做生信的同學(xué)二庵,你可以不會(huì)Python贪染,你可以不會(huì)Perl,但是R你總要會(huì)一點(diǎn)吧……

當(dāng)我們在R中合并文件時(shí)催享,我們經(jīng)常會(huì)用到merge()函數(shù)杭隙,它可以根據(jù)兩文件中指定的列進(jìn)行合并,對文件取交集因妙。換個(gè)角度想想痰憎,這個(gè)取交集的操作不就是找把B文件中存在于A文件中的行么票髓。

這里,因?yàn)槠鶈栴}铣耘,我就不介紹merge函數(shù)是如何使用的了洽沟。這個(gè)函數(shù)的原理我自己也不是很懂,只是知道是它用空間換時(shí)間蜗细,速度很快裆操,但是內(nèi)存消耗是真的大

下面是我對兩個(gè)幾百兆的文件merge時(shí)的報(bào)錯(cuò)信息炉媒,可以看到內(nèi)存溢出的那是相當(dāng)嚴(yán)重


image.png

比較機(jī)智的辦法:字典/哈希

如果你學(xué)過Python踪区,一定知道dict()字典。這個(gè)方法是真的快吊骤,就和查字典一樣缎岗,不存在遍歷的問題。這里推薦閱讀廖雪峰老師關(guān)于字典的介紹白粉,我自己的語言功底很難三兩句話把這個(gè)名詞解釋清楚传泊。

Python里面叫作字典,Perl里面似乎叫作哈希

但是該方法對于不會(huì)這兩門語言的同學(xué)友好型太差蜗元,我只是想比對個(gè)文件或渤,你卻讓我從頭開始學(xué)一門編程語言系冗?奕扣??(內(nèi)心:你這是想要我死掌敬?惯豆??奔害?)


image.png

穩(wěn)如老狗的辦法:awk命令

鋪墊了這么多楷兽,終于可以扯到重點(diǎn)上了。awk/sed/grep可以說是shell中處理數(shù)據(jù)的三劍客华临,我們大部分的數(shù)據(jù)清洗問題芯杀,都可以使用這三個(gè)方法解決。

聽起來這么牛雅潭,但是我們大部分人只會(huì)其基本操作揭厚,稍微復(fù)雜一點(diǎn)就會(huì)觸碰到我們的知識盲區(qū)……


image.png

沒關(guān)系,飯要一口一口吃扶供,畢竟肥肉不是一天長成的筛圆,頭發(fā)也不是一天就掉光的……

這里說個(gè)實(shí)話,希望不會(huì)挨打

這里簡單介紹一下awk的一些參數(shù)椿浓,只介紹稍后用到的參數(shù)太援,想了解更多闽晦,可以自行搜索學(xué)習(xí)

  • FNR:各文件分別計(jì)數(shù)的行號。當(dāng)awk命令后面跟了不止一個(gè)文件時(shí)提岔,每讀入一個(gè)新文件仙蛉,行號就要從頭開始計(jì)算。
  • NR:已經(jīng)讀出的記錄數(shù)唧垦,就是行號捅儒,從1開始,不斷累加振亮,讀入新文件也不會(huì)從頭開始計(jì)算

    比如 awk命令之后跟了兩個(gè)文件巧还,分別有3行和5行,那么FNR的值依次時(shí)1坊秸,2麸祷,3,1褒搔,2阶牍,3,4星瘾,5走孽;而NR的值則是1,2琳状,3磕瓷,4,5念逞,6困食,7,8

  • $0表示讀取的文件某一行的所有內(nèi)容翎承,$1表示某一行的第一列硕盹,$2表示某一行的第二列,以此類推
  • '[]':數(shù)組叨咖,比如a[$0]

介紹了這么多瘩例,我應(yīng)該如何使用這些參數(shù)呢?

awk 'NR==FNR {a[$0]} NR>FNR&&!($0 in a){print $0}' A.txt B.txt

這里的NR==FNR甸各,表示當(dāng)前讀取的是第一個(gè)文件A.txt的內(nèi)容垛贤,這個(gè)時(shí)候創(chuàng)建一個(gè)數(shù)組,將第一個(gè)文件的每一行內(nèi)容都作為一個(gè)key值輸入痴晦,如果不存在這個(gè)a[$0]變量南吮,則創(chuàng)建一個(gè)。通過這個(gè)方法誊酌,我們可以把文件A.txt的所有內(nèi)容逐行放入數(shù)組變量a中部凑。

接著NR>FNR表示露乏,當(dāng)前讀取的不是第一個(gè)文件(即開始讀取B.txt文件)。!($0 in a)表示當(dāng)前讀入的行涂邀,不存在之前的a數(shù)組中(即:B.txt文件中不存在于A.txt文件中的行)瘟仿。中間的&&表示前后兩個(gè)條件都要滿足,若滿足則執(zhí)行print $0命令比勉。

最終輸出的結(jié)果將是只存在于B文件中劳较,而不存在于A文件中的行。除此之外浩聋,我們可以指定比較兩個(gè)文件中的特定列观蜗,比如:

awk 'NR==FNR {a[$3]} NR>FNR&&!($2 in a){print $0}' A.txt B.txt

以上命令表示,我想找出只存在于B文件中第二列衣洁,而不存在于A文件中第三列的字段墓捻,若存在這樣的字段,則將B文件中該字段所在的行打印輸出坊夫。

這個(gè)方法砖第,速度快,容易上手环凿,基本上你會(huì)用Linux就可以梧兼。既然提到了awk命令,那就再說一個(gè)騷操作:文件去重V翘S鸾堋!

好吧瞭稼,我知道一旦說去重忽洛,你首先想到的一定是以下兩條命令:

  1. sort A.txt | uniq
  2. sort -u A.txt

這個(gè)方法固然是好腻惠,但是sort命令排序十分耗時(shí)环肘。處理小文件時(shí)我們可能體會(huì)不到,但是一旦遇到上百萬行的文件集灌,光是等待時(shí)間就夠我們喝一壺茶了悔雹。這個(gè)時(shí)候awk命令就體現(xiàn)出其重要性了。命令如下:

awk '!a[$0]++' A.txt

這里不講太多欣喧,簡單說一下這個(gè)命令執(zhí)行的步驟:

  1. 首先執(zhí)行a[$0]腌零,將輸入文件的一整行當(dāng)作數(shù)組a的key值
  2. 接著執(zhí)行!a[$0],對a[$0]的值取反唆阿,如果a[0]返回值為0益涧,則整個(gè)表達(dá)式`!a[0]`為1,執(zhí)行awk的默認(rèn)操作驯鳖,打印輸出這一行
  3. 最后是!a[$0]++闲询,對a[$0]的值加1久免,因此當(dāng)之后再遇到相同行時(shí),!a[$0]會(huì)被看作是0扭弧,不hi行默認(rèn)的打印操作

也許你覺得我講的還是不夠清楚阎姥,那么這里給你推薦一個(gè)問答,里面的第一個(gè)回答(最高贊)將這個(gè)去重的邏輯講的十分清楚鸽捻。

一點(diǎn)題外話

大部分做生信的人呼巴,對于算法都是一知半解,只求解決問題不求代碼優(yōu)美御蒲。但寫代碼衣赶,我們畢竟不是專業(yè)的。我們的終極目的是解決生物學(xué)問題厚满,而不是過多的糾結(jié)代碼的優(yōu)美性屑埋。

代碼寫的再好看,解決不了問題痰滋,依然發(fā)不了sci

另外代碼不要晚上寫摘能,一個(gè)原因是晚上寫代碼容易出bug(這是一個(gè)涉及玄學(xué)的話題),另外一個(gè)原因就是熬夜令人頭禿敲街。

最近頭有點(diǎn)涼团搞,也不知道是天氣冷了,還是頭發(fā)禿了

image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末多艇,一起剝皮案震驚了整個(gè)濱河市逻恐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌峻黍,老刑警劉巖复隆,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異姆涩,居然都是意外死亡挽拂,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進(jìn)店門骨饿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來亏栈,“玉大人,你說我怎么就攤上這事宏赘∪薇保” “怎么了?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵察署,是天一觀的道長闷游。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么脐往? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任俱济,我火速辦了婚禮,結(jié)果婚禮上钙勃,老公的妹妹穿的比我還像新娘蛛碌。我一直安慰自己,他們只是感情好辖源,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布蔚携。 她就那樣靜靜地躺著,像睡著了一般克饶。 火紅的嫁衣襯著肌膚如雪酝蜒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天矾湃,我揣著相機(jī)與錄音亡脑,去河邊找鬼。 笑死邀跃,一個(gè)胖子當(dāng)著我的面吹牛霉咨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拍屑,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼途戒,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了僵驰?” 一聲冷哼從身側(cè)響起喷斋,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蒜茴,沒想到半個(gè)月后星爪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡粉私,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年顽腾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片毡鉴。...
    茶點(diǎn)故事閱讀 38,673評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡崔泵,死狀恐怖秒赤,靈堂內(nèi)的尸體忽然破棺而出猪瞬,到底是詐尸還是另有隱情,我是刑警寧澤入篮,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布陈瘦,位于F島的核電站,受9級特大地震影響潮售,放射性物質(zhì)發(fā)生泄漏痊项。R本人自食惡果不足惜锅风,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鞍泉。 院中可真熱鬧皱埠,春花似錦、人聲如沸咖驮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽托修。三九已至忘巧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間睦刃,已是汗流浹背砚嘴。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涩拙,地道東北人际长。 一個(gè)月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像兴泥,于是被迫代替她去往敵國和親也颤。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評論 2 349

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

  • 1郁轻、Nginx日志分析日志格式:'$remote_addr - $remote_user [$time_local...
    運(yùn)維前線閱讀 707評論 0 4
  • AWK將文件shuffle time awk 'BEGIN{srand()}{b[rand()NR]=$0}END...
    MiracleJQ閱讀 623評論 0 2
  • 基礎(chǔ)命令 主要的命令和快捷鍵 Linux系統(tǒng)命令由三部分組成:cmd + [options]+[operation...
    485b1aca799e閱讀 1,088評論 0 0
  • 專業(yè)考題類型管理運(yùn)行工作負(fù)責(zé)人一般作業(yè)考題內(nèi)容選項(xiàng)A選項(xiàng)B選項(xiàng)C選項(xiàng)D選項(xiàng)E選項(xiàng)F正確答案 變電單選GYSZ本規(guī)程...
    小白兔去釣魚閱讀 8,981評論 0 13
  • 第一篇 awk簡介與表達(dá)式實(shí)例 一種名字怪異的語言 模式掃描和處理翅娶,處理數(shù)據(jù)和生成報(bào)告。 awk不僅僅是linux...
    ___n閱讀 6,698評論 0 23