資料工程師常用的 Shell 命令

雲戒發表於2016-03-24

導讀:Linux以其強大的命令列稱霸江湖,Shell命令是資料極客的必修兵器。探索性資料分析,在需求和資料都不太明確的環境下,使用各種命令進行一次探索與挖掘。從基礎的檔案檢視到簡單的統計,再到一些常用的探索性分析命令,其目的都只是為了更好的做資料分析與挖掘而已。

01 Shell命令列

對於經常和資料打交道的人來說,資料工程師應該也是常常和Linux打交道。Linux以其強大的命令列稱霸江湖,因此,Shell命令也是資料極客的必修兵器。

利用Linux命令列的幾個命令,就可以完成一些簡單的統計分析工作,比如利用wc命令統計檔案行,單詞數,字元數,利用sort排序和去重,再結合uniq可以進行詞頻統計。比如:

先用cat命令,瞭解一下檔案的大概格式與內容,發現每行為一個單詞。現在需要統計這些單詞出現的頻率,以及顯示出現次數最多的5個單詞。

先對檔案進行排序,這樣相同的單詞在緊挨著的行,再後uniq -c 命令,統計不同的單詞及各個單詞出現的次數。這樣得到的結果就是次數後面緊接著單詞,然後使用sort -nr對次數進行排序,並逆序顯示,最後head命令顯示結果的前5行。

非常簡單的一種方式,讀取檔案,排序,統計,再對統計結果進行逆序,最後只顯示前幾個結果。

類似於sql語句:

如果對sql語句熟悉的話,上面的形式應該更容易理解。雖然實現的思想和方式非常簡單,但在實際的探索性資料分析中使用卻非常頻繁。

02 探索性分析

比如在日誌分析中,有時並沒有非常明確的目標,或者即使有明確的目標,通常各種資料也並沒有明確的定義。比如,別人丟給你一個壓縮檔案,說想分析一下里面有哪些是異常的訪問請求。任務描述就是這樣,沒有更明確的了。

拿到日誌檔案和這樣的分析任務,就需要進行各種可能的探索性分析。先看一下檔案的格式,是否壓縮過,使用gzip壓縮還是tar壓縮。解壓後,需要先大概瞭解一下,檔案是什麼樣的格式。對於網路請求的日誌檔案,是一行一個請求和響應,還是多行一個請求和響應。檢視檔案有多少行,檢視檔案佔用空間大小。如果解壓後包含多個目錄或者檔案,同樣的一個命令,更能發揮強大效果。此時,通常需要如下命令:

gzip/tar:壓縮/解壓
cat/zcat:檔案檢視
less/more:檔案檢視,支援gz壓縮格式直接檢視
head/tail:檢視檔案前/後10行
wc:統計行數、單詞數、字元數
du -h -c -s:檢視空間佔用

上面有一個比較有趣的命令組,less和more,這兩個都可以分頁檢視檔案。最開始有的more命令,好像是當時more不支援向後翻頁。於是一幫人就在此基礎上進行了改進,直接叫less,和more同樣的功能只是更強大些。因此,也發展出了“less is more”的哲學,“少即是多”,而且少比多更好。這種思想,在產品設計與程式碼優化中都有體現。

瞭解檔案的大概資訊後,可能需要提取一行中某個欄位的內容,或者需要搜尋某些行出來,或者需要對某些字元或者行進行一定的修改操作,或者需要在眾多的目錄和檔案中找出某此天的日誌(甚至找到後需要對這些天的日誌進行統一處理),此時下面這些命令可以幫你:

awk:命令列下的資料庫操作工具
join/cut/paste:關聯檔案/切分欄位/合併檔案
fgrep/grep/egrep:全域性正規表示式查詢
find:查詢檔案,並且對查詢結果批量化執行任務
sed:流編輯器,批量修改、替換檔案
split:對大檔案進行切分處理,按多少行一個檔案,或者多少位元組一個檔案
rename:批量重新命名(Ubuntu上帶的perl指令碼,其它系統需要安裝),使用-n命令進行測試

如:

另外,以z開頭的幾個命令可以簡單處理gzip壓縮檔案, 如zcat:直接列印壓縮檔案,還有zgrep/zfgrep/zegrep,在壓縮檔案中直接查詢。

fgrep, grep, egrep的一些區別:

fgrep按字串的本來意思完全匹配,裡面的正則元字元當成普通字元解析, 如: fgrep “1.2.3.4” 則只匹配ip地址: 1.2.3.4, 其中的.不會匹配任意字元。fgrep當然會比grep快多了。寫起來又簡單,不用轉義。
grep只使用普通的一些正則,egrep或者grep -E使用擴充套件的正則,如

查詢所有來自日本的ip的請求,先把所有來源ip取出來,去重,找出日本的ip,放入檔案japan.ip,再使用命令:

對hive中匯出的檔案,替換01

03 其它常用命令

如果檔案編碼是從windows上傳過來的gb2312編碼,需要處理成utf8的編碼,或者某個日誌被黑客後來修改過了,需要和原來的備份資料進行對比,這些工作都是需要資料工程師自己能熟悉的掌握。

假如日誌檔案是最近一年的請求日誌,那麼可能是按天或者按小時進行單獨存放,此時如果只需要提取某些天(比如週末)的資料,很可能需要處理時間。

因此,下面的一些命令或者工具就很有用了:

date:命令列時間操作函式
sort/uniq:排序、去重、統計
comm:對兩個排序檔案進行按行比較(共同行、只出現在左邊檔案、只出現在右邊檔案)
diff:逐字元比較檔案的異同,配合cdiff,類似於github的顯示效果
curl/w3m/httpie:命令列下進行網路請求
iconv:檔案編碼轉換,如:iconv -f GB2312 -t UTF8 1.csv > 2.csv
seq:產生連續的序列,配合for迴圈使用

輸出今天/昨天的日期字串

對unix秒的處理

兩個檔案a.txt, b.txt求只出現在a.txt中的資料:

04 批量操作

對上面的檔案進行了一番探索分析後,可能已經有一定的線索或者眉目了,需要更進一步的處理大量的檔案或者欄位了。此時的步驟也許是一個消耗時間的過程,也許是一個需要看緣分的過程。總之,可能需要綜合上面的一些命令,並且對大量的日誌進行處理。

這也是體現Shell更強大的一面——批量化的功能了。命令比圖形介面的最大優勢就是,只需熟悉了,就很容易實現批量化操作,將這些批量化的命令組合成一個檔案,於是便產生了指令碼。

批量化命令或者指令碼,熟悉幾個常用的流程控制,就能發揮出強大的效能:

if條件判斷:

while迴圈:

for迴圈(用得很多):

這幾個條件判斷與迴圈,也可以直接在命令列下使用,區別是多加幾個分號隔開即可。

另外,執行長時間的任務,最好直接用nohup來操作。

生成過去8天的日期序列:

有目錄和檔案如下:

需求:去掉目錄中的*.log.gz,這樣很容易讓人誤解為檔案。 rename -n為測試,rename使用和sed相同的語法。

測試完成後,使用rename不加-n為真正執行重新命名操作。

05 結尾

這兒只是簡單列舉了一些資料分析或者資料處理相關的命令,只能算是Linux的Shell那博大精深的命令中的冰山一角。

但如果能把這些相關的命令融會貫通,並且能實際使用的話,也算是在資料極客之路上多走了一步。

從基礎的檔案檢視到簡單的統計,再到一些常用的探索性分析命令,其目的都只是為了更好的做資料分析與挖掘而已。能綜合這些命令,並組合起來使用,將命令存放到檔案,即產生了Shell指令碼。Shell指令碼本身也是一門強大的學問了,其中各個命令還有每個命令支援的引數,值得慢慢研究。

打賞支援我寫出更多好文章,謝謝!

打賞作者

打賞支援我寫出更多好文章,謝謝!

任選一種支付方式

資料工程師常用的 Shell 命令 資料工程師常用的 Shell 命令

相關文章