今天周末,導師讓我來實驗室,幫他一起把資料從伺服器上拷貝下來,然後做預先處理,周一上午給出結果。 現在幹得都差不多了,放在伺服器讓自個跑著,我閑來沒事就隨便看看新聞,逛逛論壇,寫寫部落格,回顧總結一下前天面試的經驗教訓和心得體會
先說說前天百度面試的經曆吧,那天下課後匆匆在教學樓列印代碼後,便直接騎車飛奔五道口13號地鐵站,進站、刷卡、等車、呼呼……、下車、刷卡、出站、然後從西二旗以100米衝刺的速度狂奔百度大廈,跨進B座門後,手機顯示16:48分,還好,總算沒遲到!
和一面一樣,提前5分鐘預約面試官,17:00面試正式開始 balabala... 18:00面試over。剛好面試完後,哥哥就給我打電話問我面試的情況如何(可能哥哥就站在4樓看著我面試呢 ^_^),並讓我在一樓大廳等一會,他下樓帶我去百度一樓吃飯(這個點回學校肯定也都沒飯啦) 於是我和哥哥一塊下樓到百度食堂,也隨便感受一下百度的食堂文化——哇,人好多啊!需要排隊、需要刷卡、也有免費的綠豆湯。。。有點像中科院的食堂,頗具學校食堂的氣氛——於是點了一份喜歡吃的魚和一小盤海帶絲,要了一大份米飯,端了一大碗綠豆湯,哥哥替我打卡,好好蹭飯唄 哈哈
面試的序幕和片尾都講完了,下面再回放一段精彩的劇情吧——回顧一下面試GG讓我用Linux Shell命令進行字串匹配的那道題吧(第二道)
題目大意:給出一個檔案,裡麵包含兩個欄位{url、size},url即為網址,size為網址對應訪問的次數,要求:問題1、利用Linux Shell命令或自己設計演算法,查詢出url字串中包含“baidu”子字串對應的size欄位值;問題2、根據問題1的查詢結果,對其按照size由大到小的排列
面試時我採用的是自己設計演算法,面試回來後我man sort查了排序命令的參數使用手冊,下面我就詳細講一下用Shell命令的做法
分析題意:baidu.txt{url, size},baidu.txt是檔案,{url, size}是檔案中的兩個欄位,並且url和size都是字串型,欄位之間用tab(/t)隔開
第一步,查詢匹配url字串中的字串"baidu",直接用grep命令,具體格式 grep "baidu" baidu.txt(每行僅url可能含有baidu子字串)
第二步,顯示含有字串"baidu"的url及其對應的size,可以直接用ls命令,具體格式 ls -l | grep "baidu" baidu.txt(管道傳值)
第三步,將步驟2的結果,通過重新導向命令>>儲存在baidu2.txt檔案中,即 grep "baidu" baidu.txt >> baidu2.txt 儲存匹配結果
第四步,排序,直接利用sort命令,即格式ls -l | sort -rnk 2 baidu.txt (sort反向r、以第二個欄位k 2、數值型n進行排序)
第五步,將步驟4的結果,通過重新導向命令>>儲存在baidu3.txt檔案中,即 sort -rnk 2 baidu2.txt >> baidu3.txt 儲存排序結果
按照上面五步,我們先看結果,用資料說話,然後我將在下面依次詳細介紹上面五步中用到的Shell命令及其參數的確切含義:
首先,建立baidu.txt檔案,即用Vim編輯器輸入建立的測試案例(我用過的主流搜尋引擎及百度的部分產品),然後利用cat命令查看檔案
其次,我們查詢url字串中包含子串"baidu"的項,並列印出url及其size
然後,我們建立baidu2.txt檔案,用於儲存問題1的結果(即匹配字串url中包含子串"baidu"的結果項url和size)
接著,我們對上述問題1的結果,利用sort命令按照size由大到小進行排序
最後,我們建立baidu3.txt檔案,用於儲存sort排序結果
附圖說明:
以上,均截自我電腦Linux RedHat 5.2(安裝在VMWare 7.0虛擬機器上)
其中的Shell命令都在Redhat Linux OS環境已測試通過
====================================================================================
好啦,今晚在man sort 查看了sort詳細參數使用方法後,似乎可以不用awk命令就可以搞定此題,看來並沒有我面試時想得那麼複雜。現在就讓我們具體看看sort的參數以及grep、重新導向等Shell命令的詳細使用方法吧
sort命令
格式:sort 【參數】 【檔案】
舉例:sort -rnk 2 baidu.txt
參數:r 逆序; n字串按數值處理; k 2 表示第二個欄位(列)
說明:在檔案baidu.txt中,按照第二個欄位的數值型由大到小進行排序
首先,在 Linux Shell命令列介面輸入 man sort 查看 sort 的協助手冊
然後,查看本題中,我們需要用到的三個參數 r n k 的詳細使用方法
由sort協助文檔顯示:
1、參數n是把string字串轉換成numberical的值value進行比較(即把字串轉換成數值型,再進行比較)
2、參數r是反向,即逆序。由於sort預設排序是由小到大,而題意需要從大到小排序,因此此處需要逆序(注意:v在某些命令中也可表示反向,如Regex中)
3、參數k是欄位分隔,即從哪個欄位開始直到哪個欄位結束,按其進行排序(注意:Linux Redhat 第一列從1開始,而不是0,本題格式中size為第二列,因此我們k定為2,而不是1。區別於通常用的Array數組下限和Python語言中分組的下限,即從0開始)
grep命令
格式:grep 【參數】 【查詢字串】 【檔案】
舉例:grep "baidu" baidu.txt
參數:此處無參數(省略了參數)
說明:查詢匹配檔案baidu.txt中,判斷是否包含"baidu"子字串
在Linux Shell命令列輸入:man grep
管道| 命令
格式:【命令1】(目標) |【命令2】(來源資料)
參數:為進程通訊,無參數
舉例:ls -l | grep "baidu" baidu.txt
說明:把檔案baidu.txt中,包含"baidu"子字串的結果,通過管道|命令,傳給ls -l 作為目標內容,進行顯示
重新導向>或>> 命令
格式:【命令1】(來源資料)> 【命令2】(目標) 或者 【命令1】(來源資料)>> 【命令2】(目標)
參數:為通道傳值,無參數
舉例:sort -rnk 2 baidu.txt > baidu2.txt
說明:把檔案baidu.txt中,對第二個欄位按照數值型進行由大到小的排序,並將結果儲存到檔案baidu2.txt(清空後重寫)
附圖舉例說明:先清空檔案baidu2.txt中原有內容,然後再將sort結果重新導向儲存到baidu2.txt檔案中
附圖舉例說明:先並未清空檔案baidu2.txt中原有內容,而是直接追加sort結果,重新導向儲存到baidu2.txt檔案中(保留baidu2.txt原有內容)
ls touch cat等其它基本命令,請詳見我先前的部落格 Linux Shell 常用命令與目錄分割的學習總結
====================================================================================
第二步,查詢匹配url字串中是否含有字串"baidu"的另一種做法(在網友showmsg 的提示下,改用 awk 命令代替 grep 命令進行正則匹配)
當然,我們還是先看結果,然後我再介紹awk命令的使用方法
首先,我們查詢並列印出含有"baidu"字串的url及其size
其次,我們對查詢含有"baidu"的結果,對size進行有大到小的排序
最後,儲存查詢匹配"baidu"並對size由大到小排序後的結果到baidu2.txt檔案中(重新導向)
附加1,如果只想按照size由大到小列印出url(即不列印size,也就是分離欄位),則如下
附加2,如果只想按照size由大到小列印出size(即不列印url,也就是分離欄位),則如下
這便是我面試時想用awk命令的解法,不過當時我只知道此命令功能但沒具體用過,今在網友showmsg 指點下,總算略通一二,對此表示謝意^_^
====================================================================================
awk 命令
格式:awk commands file 或者 awk script-file file
參數:print 列印;$1 第一個欄位; $2 第二個欄位; ' ' 單引號需加上,並可寫入Regex,如查詢baidu字串
舉例:awk '/baidu/ && $2<800' baidu.txt
說明:查詢檔案baidu.txt中滿足第一欄位含有"baidu"字串並且第二個欄位數字size<800的所有記錄,並顯示出結果
附圖1:查詢檔案baidu.txt中滿足第一欄位含有"baidu"字串並且第二個欄位數字size<800的所有記錄,並顯示出結果
附圖2:查詢檔案baidu.txt中滿足第一欄位含有"baidu"字串並且第二個欄位數字size<800的所有記錄,並列印出結果的第一個欄位(url)