對於許多數據科學家來講,數據操做起始於Pandas或Tidyverse。從理論上看,這個概念沒有錯。畢竟,這是爲何這些工具首先存在的緣由。然而,對於分隔符轉換等簡單任務來講,這些選項一般多是過於重量級了。git
有意掌握命令行應該在每一個開發人員的技能鏈上,特別是數據科學家。學習shell中的前因後果無能否認地會讓你更高效。除此以外,命令行還在計算方面有一次偉大的歷史記錄。例如,awk - 一種數據驅動的腳本語言。Awk首次出現於1977年,它是在傳奇的K&R一書中的K,Brian Kernighan的幫助下出現的。在今天,大約50年以後,awk仍然與每一年出現的新書保持相關聯! 所以,能夠確定的是,對命令行技術的投入不會很快貶值的。正則表達式
若是你想了解大數據的學習路線,想學習大數據知識以及須要免費的學習資料能夠加羣:784789432.歡迎你的加入。天天下午三點開直播分享基礎知識,晚上20:00都會開直播給你們分享大數據項目實戰。sql
咱們會談及的內容shell
- ICONV
- HEAD
- TR
- WC
- SPLIT
- SORT & UNIQ
- CUT
- PASTE
- JOIN
- GREP
- SED
- AWK
- ICONV
文件編碼老是棘手的問題。目前大部分文件都是採用的 UTF-8 編碼。要想了解 UTF-8 的魔力,能夠看看這個優秀的視頻。儘管如此,有時候咱們仍是會收到非 UTF-8 編碼的文件。這種狀況下就須要嘗試轉碼。iconv 就是這種情況下的救世主。iconv 是一個簡單的程序,能夠輸入某種編碼的文本,而後以另外一種編碼輸出。ruby
- # Converting -f (from) latin1 (ISO-8859-1)
- # -t (to) standard UTF_8
-
- iconv -f ISO-8859-1 -t UTF-8 < input.txt > output.txt
經常使用選項:less
- iconv -l 列出全部支持的編碼
- iconv -c 不做提示就丟棄沒法轉換的字符
HEAD編輯器
若是你是重度Pandas的用戶,那麼你會對head很熟悉。一般在處理新數據時,咱們想要作的第一件事就是了解究竟存在那些東西。這會引發Panda啓動,讀取數據,而後調用df.head() - 很費勁,至少能夠說。head,不須要任何標誌,將輸出文件的前10行。head真正的能力在於徹查清除操做。 例如,若是咱們想將文件的分隔符從逗號改變爲pipe通配符。一個快速測試將是:head mydata.csv | sed 's/,/|/g'函數
- # Prints out first 10 lines
- head filename.csv
- # Print first 3 lines
- head -n 3 filename.csv
有用的選項:工具
- head -n 輸出指定行
- head -c 輸出指定的字節
TR命令學習
Tr相似於翻譯,它是基於文件清理的一個強大使用的工具。一個理想的用法是替換文件中的分隔符。
- #將文件中的製表符分割轉換成逗號
- cat tab_delimited.txt | tr "\t" "," comma_delimited.csv
Tr的另外一個特性是在你的處理中設置上全部的[:class:]變量。包括:
- [:alnum:] 全部字母和數字
- [:alpha:] 全部字母
- [:blank:] 全部水平空白
- [:cntrl:] 全部控制字符
- [:digit:] 全部數字
- [:graph:] 全部可打印的字符,不包括空格
- [:lower:] 所有小寫字母
- [:print:] 全部可打印的字符,包括空格
- [:punct:] 全部標點符號
- [:space:] 全部的水平或垂直空格
- [:upper:] 所有大寫字母
- [:xdigit:] 全部十六進制數字
能夠將這些多樣化的變量連接在一塊兒,組成一個強大的程序。下面是一個基於字數統計的程序,用來檢查你的README文件是否使用過分。
- cat README.md | tr "[:punct:][:space:]" "\n" | tr "[:upper:]" "[:lower:]" | grep . | sort | uniq -c | sort -nr
另一個例子用於正則表達式
- # 將全部的大寫字母轉換成小寫
- cat filename.csv | tr '[A-Z]' '[a-z]'
有用的選項:
- tr -d刪除字符
- tr -s壓縮字符
- \b退格
- \f換頁
- \v垂直選項卡
- \NNN八進制值爲NNN的字符
WC
字數統計。它的價值主要體如今使用 -l 參數能夠進行行數統計。
- # Will return number of lines in CSV
- wc -l gigantic_comma.csv
個用這個工具來驗證各個命令的輸出實在方便。所以,若是咱們要在文件中轉換分隔符,而後運行 wc -l,驗證總行數是相同的。若是不一樣,咱們就知道必定是哪裏出錯了。
經常使用選項:
- wc -c 打印字節數
- wc -m 打印字符數
- wc -L 打印最長一行的長度
- wc -w 打印字數
SPLIT命令
文件大小能夠有顯著變化。根據工做的不一樣,拆分文件是有益的,就像split。基本用法以下:
- #咱們拆分這個CSV文件,每500行分割爲一個新的文件new_filename
-
- split -l 500 filename.csv new_filename_
-
- # filename.csv
- # ls output
- # new_filename_aaa
- # new_filename_aab
- # new_filename_aac
兩個地方很奇怪:一個是命名方式,一個是缺乏擴展名。後綴約定能夠經過-d標識來數字化。添加文件擴展名,你須要執行下面這個find命令。他會給當前文件夾下的全部文件追加.csv後綴,因此須要當心使用。
- find . -type f -exec mv '{}' '{}'.csv \;
-
- # ls output
- # filename.csv.csv
- # new_filename_aaa.csv
- # new_filename_aab.csv
- # new_filename_aac.csv
有效的選項:
- split -b按特定字節大小拆分
- split -a生成長度爲N的後綴
- split -x使用十六進制後綴分割
SORT & UNIQ
前面的命令是顯而易見的:他們按照本身說的作。這二者提供了最重要的一擊(即去重單詞計數)。這是因爲有uniq,它只處理重複的相鄰行。所以在管道輸出以前進行排序。一個有趣的事情是,sort -u將得到與sort file.txt | uniq相同的結果。
Sort確實對數據科學家來講是一種頗有用的小技巧:可以根據特定的列對整個CSV進行排序。
- # Sorting a CSV file by the second column alphabetically
- sort -t"," -k2,2 filename.csv
- # Numerically
- sort -t"," -k2n,2 filename.csv
- # Reverse order
- sort -t"," -k2nr,2 filename.csv
這裏的-t選項是指定逗號做爲分隔符。一般假設是空格或製表符。此外,-k標誌是用來指定咱們的鍵的。它的語法是-km,n,m是起始字段,n是最後一個字段。
有用的選項:
- sort -f 忽略大小寫
- sort -r 逆序
- sort -R 亂序
- uniq -c 計算出現次數
- uniq -d 只打印重複行
CUT命令
cut用於刪除列。舉個栗子,若是咱們只想要第一列和第三列。
- cut -d, -f 1,3 filename.csv
選擇除了第一列之外的全部列
- cut -d, -f 2- filename.csv
與其餘的命令組合使用,cut命令做爲過濾器
- #打印存在「some_string_value」的第1列和第3列的前10行
- head filename.csv | grep "some_string_value" | cut -d, -f 1,3
找出第二列中惟一值的數量。
- cat filename.csv | cut -d, -f 2 | sort | uniq | wc -l
- # 計算惟一值出現的次數,限制輸出前10個結果
- cat filename.csv | cut -d, -f 2 | sort | uniq -c | head
PASTE
paste 是個有趣的小命令。若是你想合併兩個文件,而這兩個文件的內容又正好是有序的,那 paste 就能夠這樣作。
- # names.txt
- adam
- john
- zach
-
- # jobs.txt
- lawyer
- youtuber
- developer
-
- # Join the two into a CSV
-
- paste -d ',' names.txt jobs.txt > person_data.txt
-
- # Output
- adam,lawyer
- john,youtuber
- zach,developer
關於更多 SQL_-esque 變體,請看下面。
JOIN
Join是一種簡單的、準切向的SQL。最大的區別在於Join將返回全部列,匹配可能只發生在一個字段上。默認狀況下,join將嘗試使用第一列做爲匹配鍵。對於不一樣的結果,須要如下語法:
- # Join the first file (-1) by the second column
- # and the second file (-2) by the first
-
- join -t"," -1 2 -2 1 first_file.txt second_file.txt
標準鏈接是一個內部鏈接。然而,外部鏈接也能夠經過-af滯後來實現。另外一個值得注意的是-e標誌,若是發現有字段丟失,它能夠用來替換成其餘值。
- # Outer join, replace blanks with NULL in columns 1 and 2
- # -o which fields to substitute - 0 is key, 1.1 is first column, etc...
-
- join -t"," -1 2 -a 1 -a2 -e ' NULL' -o '0,1.1,2.2' first_file.txt second_file.txt
雖然它不是最容易使用的命令,可是在絕望的時刻,它就是惟一可用的措施。
經常使用的選項:
- join -a 打印未成對的行
- join -e 替換缺失字段
- join -j 等同於 -1 FIELD -2 FIELD
GREP
全局搜索正則表達式並輸出,或使用grep;多是最知名的命令,而且有很好的理由。 Grep具備很強的能力,特別是在大型代碼庫中查找方法。在數據科學領域,它充當了其餘命令的改進機制。但其標準用法也頗有用。
- # 遞歸搜索並列出當前目錄下包含'word'的全部文件
- grep -lr 'word' .
-
- # 列出包含word的文件數目
- grep -lr 'word' . | wc -l
對包含word/pattern的行數進行計數
- grep -c 'some_value' filename.csv
- # 一樣的功能,可是按照文件名列出當前目錄下全部包含該關鍵詞的文件
- grep -c 'some_value' *
Grep使用or運算符- \|來檢索多個值.
- grep "first_value\|second_value" filename.csv
有用的選項
- alias grep="grep --color=auto" 使grep支持彩色輸出
- grep -E 使用擴展正則表達式
- grep -w 僅匹配完整單詞
- grep -l 打印匹配文件的名稱
- grep -v 倒序匹配
大殺器
Sed和Awk是本文兩個最有用的命令。爲了簡潔,我不會討論那些使人費解的細節。相反,我會討論各類各樣的命令來證實他們使人印象深入的實力。若是你想了解的更多,這本書就能夠。
SED
在內核中sed是一個流編輯器。它擅長替換,可是也能夠用來重構。
最基本的sed命令包含了s/old/new/g。也就是全局搜索舊值,替換新值。沒有/g 咱們的命令可能在第一次出現舊值就會終止。
爲了儘快瞭解它的能力,咱們來看一個例子。在這個狀況你會拿到下面的文件:
- balance,name
- $1,000,john
- $2,000,jack
咱們要作的第一件事就是移除美圓符。-i 標識表示就地修改。''就是表明一個零長度文件擴展,所以重寫咱們的初始文件。理想狀況下,你會單獨測試這些並輸出到一個新文件。
- sed -i '' 's/\$//g' data.txt
-
- # balance,name
- # 1,000,john
- # 2,000,jack
下一步,咱們的balance列的逗號。
- sed -i '' 's/\([0-9]\),\([0-9]\)/\1\2/g' data.txt
-
- # balance,name
- # 1000,john
- # 2000,jack
最終,Jack有一天起來並準備辭職了。因此,再見吧,個人朋友。
- sed -i '' '/jack/d' data.txt
-
- # balance,name
- # 1000,john
就像你所看到的,sed功能強大,可是樂趣不止於此。
AWK
最好的放最後。Awk不只是一個簡單的命令:它是一個成熟的語言。在本文中包含的每個命令中,awk目前是最酷的。若是你發現它令你印象深入,這有大量的資源- 看這,這,和這。
awk包含的經常使用案例:
- 文本處理
- 格式化文本報告
- 執行計算操做
- 執行字符串操做
Awk在其最初雛形能夠與grep平行。
- awk '/word/' filename.csv
或者多使用一點魔法,讓grep和cut結合。在這,awk對全部行經過word打印了以tab分隔的第三和第四列。-F,只是將分隔符變爲逗號。
- awk -F, '/word/ { print $3 "\t" $4 }' filename.csv
Awk具備大量有用的內置變量。例如, NF -字段數 - 和NR - 記錄數。爲了獲取文件中這53個記錄:
- awk -F, 'NR == 53' filename.csv
添加一個小竅門能夠基於一個值或者多個值過濾。下面的第一個例子,會打印這些記錄中第一列爲string的行數和列。
- awk -F, ' $1 == "string" { print NR, $0 } ' filename.csv
- # Filter based off of numerical value in second column
- awk -F, ' $2 == 1000 { print NR, $0 } ' filename.csv
多數值表達式:
- # Print line number and columns where column three greater
- # than 2005 and column five less than one thousand
-
- awk -F, ' $3 >= 2005 && $5 <= 1000 { print NR, $0 } ' filename.csv
計算第三列之和:
- awk -F, '{ x+=$3 } END { print x }' filename.csv
計算那些第一列值爲「something」的第三列之和。
- awk -F, '$1 == "something" { x+=$3 } END { print x }' filename.csv
獲取文件的行數列數:
- awk -F, 'END { print NF, NR }' filename.csv
- # Prettier version
- awk -F, 'BEGIN { print "COLUMNS", "ROWS" }; END { print NF, NR }' filename.csv
打印出現過兩次的行:
- awk -F, '++seen[$0] == 2' filename.csv
移除多行:
- # Consecutive lines
- awk 'a !~ $0; {a=$0}']
-
- # Nonconsecutive lines
- awk '! a[$0]++' filename.csv
-
- # More efficient
- awk '!($0 in a) {a[$0];print}
使用內置函數gsub()替換多個值。
- awk '{gsub(/scarlet|ruby|puce/, "red"); print}'
這個awk命令合併了多個CSV文件,忽略頭並在結尾追加。
- awk 'FNR==1 && NR!=1{next;}{print}' *.csv > final_file.csv
須要精簡一個大文件?好的,awk能夠在sed的幫助下完成這件事。具體來講,基於一個行數,這個命令將一個大文件分爲多個小文件。這個一行文件也會添加一個擴展名。
- sed '1d;$d' filename.csv | awk 'NR%NUMBER_OF_LINES==1{x="filename-"++i".csv";}{print > x}'
- # Example: splitting big_data.csv into data_(n).csv every 100,000 lines
- sed '1d;$d' big_data.csv | awk 'NR%100000==1{x="data_"++i".csv";}{print > x}'
結束前
命令行擁有無窮的力量。本文所涵蓋的命令行知識足以讓你從零基礎到入門。除了這些已涉及的內容外,針對平常數據操做還有須要可考慮的實用程序。Csvkit, xsv和q是其中三個值得關注的。若是你但願進一步深刻到命令行的數據科學領域,那麼請看此書。它也能夠在此免費得到!