摘抄:http://blog.jobbole.com/114238/
我們會談及的內(nèi)容
- ICONV
- HEAD
- TR
- WC
- SPLIT
- SORT & UNIQ
- CUT
- PASTE
- JOIN
- GREP
- SED
- AWK
ICONV
文件編碼總是棘手的問題娄柳。目前大部分文件都是采用的 UTF-8 編碼叮雳。要想了解 UTF-8 的魔力,可以看看這個優(yōu)秀的視頻圆裕。盡管如此陋桂,有時候我們還是會收到非 UTF-8 編碼的文件逆趣。這種情況下就需要嘗試轉(zhuǎn)碼。iconv 就是這種狀況下的救世主嗜历。iconv 是一個簡單的程序宣渗,可以輸入某種編碼的文本抖所,然后以另一種編碼輸出。
# Converting -f (from) latin1 (ISO-8859-1)
# -t (to) standard UTF_8
iconv -f ISO-8859-1 -t UTF-8 < input.txt > output.txt
- 常用選項:
- iconv -l 列出所有支持的編碼
- iconv -c 不作提示就丟棄無法轉(zhuǎn)換的字符
HEAD
如果你是重度Pandas的用戶落包,那么你會對head很熟悉部蛇。通常在處理新數(shù)據(jù)時摊唇,我們想要做的第一件事就是了解究竟存在那些東西咐蝇。這會引起Panda啟動,讀取數(shù)據(jù)巷查,然后調(diào)用df.head()
– 很費勁有序,至少可以說。head岛请,不需要任何標(biāo)志旭寿,將輸出文件的前10行。head真正的能力在于徹查清除操作崇败。 例如盅称,如果我們想將文件的分隔符從逗號改變?yōu)閜ipe通配符。一個快速測試將是: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 輸出指定的字節(jié)
TR命令
Tr類似于翻譯后室,它是基于文件清理的一個強大使用的工具缩膝。一個理想的用法是替換文件中的分隔符。
#將文件中的制表符分割轉(zhuǎn)換成逗號
cat tab_delimited.txt | tr "\t" "," comma_delimited.csv
Tr的另一個特性是在你的處理中設(shè)置上所有的[:class:]
變量岸霹。包括:
[:alnum:] 所有字母和數(shù)字
[:alpha:] 所有字母
[:blank:] 所有水平空白
[:cntrl:] 所有控制字符
[:digit:] 所有數(shù)字
[:graph:] 所有可打印的字符疾层,不包括空格
[:lower:] 全部小寫字母
[:print:] 所有可打印的字符,包括空格
[:punct:] 所有標(biāo)點符號
[:space:] 所有的水平或垂直空格
[:upper:] 全部大寫字母
[:xdigit:] 所有十六進制數(shù)字
可以將這些多樣化的變量鏈接在一起贡避,組成一個強大的程序痛黎。下面是一個基于字?jǐn)?shù)統(tǒng)計的程序,用來檢查你的README文件是否使用過度刮吧。
cat README.md | tr "[:punct:][:space:]" "\n" | tr "[:upper:]" "[:lower:]" | grep . | sort | uniq -c | sort -nr
另外一個例子用于正則表達式
# 將所有的大寫字母轉(zhuǎn)換成小寫
cat filename.csv | tr '[A-Z]' '[a-z]'
- 有用的選項:
- tr -d刪除字符
- tr -s壓縮字符
- \b退格
- \f換頁
- \v垂直選項卡
- \NNN八進制值為NNN的字符
WC
字?jǐn)?shù)統(tǒng)計湖饱。它的價值主要體現(xiàn)在使用 -l
參數(shù)可以進行行數(shù)統(tǒng)計。
# Will return number of lines in CSV
wc -l gigantic_comma.csv
個用這個工具來驗證各個命令的輸出實在方便杀捻。因此井厌,如果我們要在文件中轉(zhuǎn)換分隔符,然后運行 wc -l水醋,驗證總行數(shù)是相同的旗笔。如果不同,我們就知道一定是哪里出錯了拄踪。
- 常用選項:
- wc -c 打印字節(jié)數(shù)
- wc -m 打印字符數(shù)
- wc -L 打印最長一行的長度
- wc -w 打印字?jǐn)?shù)
SPLIT命令
文件大小可以有顯著變化蝇恶。根據(jù)工作的不同,拆分文件是有益的惶桐,就像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標(biāo)識來數(shù)字化。添加文件擴展名贸辈,你需要執(zhí)行下面這個find命令释树。他會給當(dāng)前文件夾下的所有文件追加.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按特定字節(jié)大小拆分
- split -a生成長度為N的后綴
- split -x使用十六進制后綴分割
SORT & UNIQ
前面的命令是顯而易見的:他們按照自己說的做奢啥。這兩者提供了最重要的一擊(即去重單詞計數(shù))。這是由于有uniq
嘴拢,它只處理重復(fù)的相鄰行桩盲。因此在管道輸出之前進行排序。一個有趣的事情是席吴,sort -u
將獲得與sort file.txt | uniq
相同的結(jié)果赌结。
Sort
確實對數(shù)據(jù)科學(xué)家來說是一種很有用的小技巧:能夠根據(jù)特定的列對整個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
選項是指定逗號作為分隔符孝冒。通常假設(shè)是空格或制表符柬姚。此外,-k
標(biāo)志是用來指定我們的鍵的迈倍。它的語法是-km,n
伤靠,m是起始字段,n是最后一個字段啼染。
- 有用的選項:
- sort -f 忽略大小寫
- sort -r 逆序
- sort -R 亂序
- uniq -c 計算出現(xiàn)次數(shù)
- uniq -d 只打印重復(fù)行
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
找出第二列中唯一值的數(shù)量。
cat filename.csv | cut -d, -f 2 | sort | uniq | wc -l
# 計算唯一值出現(xiàn)的次數(shù)斜棚,限制輸出前10個結(jié)果
cat filename.csv | cut -d, -f 2 | sort | uniq -c | head
PASTE
paste 是個有趣的小命令阀蒂。如果你想合并兩個文件,而這兩個文件的內(nèi)容又正好是有序的弟蚀,那 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
關(guān)于更多 SQL_-esque 變體,請看下面义钉。
JOIN
Join是一種簡單的昧绣、準(zhǔn)切向的SQL。最大的區(qū)別在于Join將返回所有列捶闸,匹配可能只發(fā)生在一個字段上夜畴。默認(rèn)情況下拖刃,join將嘗試使用第一列作為匹配鍵。對于不同的結(jié)果贪绘,需要以下語法:
# 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
標(biāo)準(zhǔn)連接是一個內(nèi)部連接兑牡。然而,外部連接也可以通過-af滯后來實現(xiàn)税灌。另一個值得注意的是-e標(biāo)志均函,如果發(fā)現(xiàn)有字段丟失,它可以用來替換成其他值垄琐。
# 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具有很強的能力,特別是在大型代碼庫中查找方法牛哺。在數(shù)據(jù)科學(xué)領(lǐng)域陋气,它充當(dāng)了其他命令的改進機制。但其標(biāo)準(zhǔn)用法也很有用引润。
# 遞歸搜索并列出當(dāng)前目錄下包含'word'的所有文件
grep -lr 'word' .
# 列出包含word的文件數(shù)目
grep -lr 'word' . | wc -l
對包含word/pattern的行數(shù)進行計數(shù)
grep -c 'some_value' filename.csv
# 同樣的功能巩趁,但是按照文件名列出當(dāng)前目錄下所有包含該關(guān)鍵詞的文件
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是本文兩個最有用的命令。為了簡潔淳附,我不會討論那些令人費解的細(xì)節(jié)议慰。相反,我會討論各種各樣的命令來證明他們令人印象深刻的實力奴曙。如果你想了解的更多别凹,這本書就可以。
SED
在內(nèi)核中sed是一個流編輯器洽糟。它擅長替換炉菲,但是也可以用來重構(gòu)。
最基本的sed命令包含了s/old/new/g
坤溃。也就是全局搜索舊值拍霜,替換新值。沒有/g 我們的命令可能在第一次出現(xiàn)舊值就會終止薪介。
為了盡快了解它的能力祠饺,我們來看一個例子。在這個情況你會拿到下面的文件:
balance,name
$1,000,john
$2,000,jack
我們要做的第一件事就是移除美元符昭灵。-i
標(biāo)識表示就地修改吠裆。"
就是代表一個零長度文件擴展伐谈,因此重寫我們的初始文件。理想情況下试疙,你會單獨測試這些并輸出到一個新文件诵棵。
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有一天起來并準(zhǔn)備辭職了。所以怀跛,再見吧距贷,我的朋友。
sed -i '' '/jack/d' data.txt
# balance,name
# 1000,john
就像你所看到的吻谋,sed功能強大忠蝗,但是樂趣不止于此。
AWK
最好的放最后漓拾。Awk不僅是一個簡單的命令:它是一個成熟的語言阁最。在本文中包含的每一個命令中,awk目前是最酷的骇两。如果你發(fā)現(xiàn)它令你印象深刻速种,這有大量的資源- 看這,這低千,和這配阵。
awk包含的常用案例:
- 文本處理
- 格式化文本報告
- 執(zhí)行計算操作
- 執(zhí)行字符串操作
Awk在其最初雛形可以與grep平行。
awk '/word/' filename.csv
或者多使用一點魔法示血,讓grep和cut結(jié)合棋傍。在這,awk對所有行通過word打印了以tab分隔的第三和第四列矾芙。-F
舍沙,只是將分隔符變?yōu)槎禾枴?/p>
awk -F, '/word/ { print $3 "\t" $4 }' filename.csv
Awk具有大量有用的內(nèi)置變量。例如剔宪, NF -字段數(shù) – 和NR – 記錄數(shù)拂铡。為了獲取文件中這53個記錄:
awk -F, 'NR == 53' filename.csv
添加一個小竅門可以基于一個值或者多個值過濾。下面的第一個例子葱绒,會打印這些記錄中第一列為string的行數(shù)和列感帅。
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
多數(shù)值表達式:
# 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
獲取文件的行數(shù)列數(shù):
awk -F, 'END { print NF, NR }' filename.csv
# Prettier version
awk -F, 'BEGIN { print "COLUMNS", "ROWS" }; END { print NF, NR }' filename.csv
打印出現(xiàn)過兩次的行:
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}
使用內(nèi)置函數(shù)gsub()替換多個值地淀。
awk '{gsub(/scarlet|ruby|puce/, "red"); print}'
這個awk命令合并了多個CSV文件失球,忽略頭并在結(jié)尾追加。
awk 'FNR==1 && NR!=1{next;}{print}' *.csv > final_file.csv
需要精簡一個大文件?好的实苞,awk可以在sed的幫助下完成這件事豺撑。具體來說,基于一個行數(shù)黔牵,這個命令將一個大文件分為多個小文件聪轿。這個一行文件也會添加一個擴展名。
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}'