SHELL 命令行技巧

摘抄: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}'
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末猾浦,一起剝皮案震驚了整個濱河市陆错,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌金赦,老刑警劉巖音瓷,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異夹抗,居然都是意外死亡绳慎,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門兔朦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來偷线,“玉大人,你說我怎么就攤上這事沽甥。” “怎么了乏奥?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵摆舟,是天一觀的道長。 經(jīng)常有香客問我邓了,道長恨诱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任骗炉,我火速辦了婚禮照宝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘句葵。我一直安慰自己厕鹃,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布乍丈。 她就那樣靜靜地躺著剂碴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪轻专。 梳的紋絲不亂的頭發(fā)上忆矛,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天,我揣著相機與錄音请垛,去河邊找鬼催训。 笑死洽议,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的漫拭。 我是一名探鬼主播亚兄,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼嫂侍!你這毒婦竟也來了儿捧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤挑宠,失蹤者是張志新(化名)和其女友劉穎菲盾,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體各淀,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡懒鉴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了碎浇。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片临谱。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖奴璃,靈堂內(nèi)的尸體忽然破棺而出悉默,到底是詐尸還是另有隱情,我是刑警寧澤苟穆,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布抄课,位于F島的核電站,受9級特大地震影響雳旅,放射性物質(zhì)發(fā)生泄漏跟磨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一攒盈、第九天 我趴在偏房一處隱蔽的房頂上張望抵拘。 院中可真熱鬧,春花似錦型豁、人聲如沸僵蛛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽墩瞳。三九已至,卻和暖如春氏豌,著一層夾襖步出監(jiān)牢的瞬間喉酌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留泪电,地道東北人般妙。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像相速,于是被迫代替她去往敵國和親碟渺。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348

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