實踐中,你用過哪些由簡單命令組裝起來的複雜命令行?

曾經在"The Unix Programming Environment"這本書里,學到這樣一個命令(這裡沒有去翻原書,不保證一模一樣,但基本差不多):

cat english.txt | sed s/[^a-zA-Z]/
/g | tr [A-Z] [a-z] | sort | uniq -c | sort -k 1 -n -r | awk NF==2 | head -20

這個命令的功能是輸出文本文件english.txt中出現次數最高的前20個單詞,除了沒有考慮詞的屈折變化,功能基本算是完善。

早年,我開始讀自然語言處理方向研究生時,曾經用過這樣的管道程序:

cat chinese.txt | sentence | word_segmentation | pos_tagging | parsing | EBMT

這個命令是對輸入中文chinese.txt,依次進行斷句、分詞、詞性標註、句法分析,最後做基於實例的機器翻譯(當年還沒有什麼深度學習,這些步驟沒有融合)。

此外,我在下面這個回答中,

知乎 - 知乎

所用的命令為:

cat *.h *.cpp | fgrep -o -w -f all.reserved-words-c++.txt | sort | uniq -c | sort -k1 -n -r

問題:你在實際工作中,還使用過什麼樣的由很簡單命令組裝起來的複雜命令行?組裝機制不限於管道,但最好不是單一AWK程序放到一行的那種。


之前查內存泄漏,在alloc和free的地方列印日誌,用ptr關聯一對申請釋放,並打出size和backtrace,用一段grep和awk統計topN申請未釋放的alloc位置

egrep "#ALLOC|#FREE" | awk {if ($6 == "#ALLOC") {a[$7]=$0} else if ($6 == "#FREE") {delete a[$7]}} END{for (k in a) {print a[k]}} | awk {for (i=8; i&<=NF; i++) {printf("%s ", $i)} printf(" ")} | sort | uniq -c | awk {printf("%d %s ", $1*$2, $0)} | sort -n -k 1

還有一個是用樹莓派接上公司辦公網,通過兩層反向ssh代理來越過relay機器,但是pi重啟後我不知道它的新ip,所以搞了個crontab,讓pi把ifconfig寫到s3。所以越過relay的登錄腳本就是先curl s3,拿到地址後再兩跳去開發機。。。


這麼好的問題,怎麼沒什麼人來回答呢。我自己先拋個磚,有好的回答後,我還會持續更新此答案。

研究期貨市場時,有時我需要知道某個合約自上市以來每天的平均價格,我把當前研究的所有價格數據放到everythinginone.txt中,具體格式實例如下:

2004-12-16 ISF2005.csv 0 0 0 524.0
2004-12-17 ISF2005.csv 0 0 0 524.0
2004-12-20 ISF2005.csv 0 0 0 524.0
2004-12-21 ISF2005.csv 0 0 0 524.0
2004-12-22 ISF2005.csv 0 0 0 524.0
2004-12-23 ISF2005.csv 0 0 0 524.0
2004-12-27 ISF2005.csv 0 0 0 524.0
2004-12-28 ISF2005.csv 0 0 0 524.0
2004-12-29 ISF2005.csv 0 0 0 524.0
2004-12-30 ISF2005.csv 0 0 0 524.0

這樣,比如我想得到ISF2010合約的平均價格數據,可以用這個命令:

cat everytinginone.txt | grep ISF2010 | awk {n++; s+=$6; print NR, s/n} &> avg

得到的avg文件大概長這樣:

1 1461.75
2 1436.75
3 1426.75
4 1411.75
5 1392.75
6 1379.25
7 1368.18
8 1358.12
9 1351.42
10 1341.05

然後,可以在上述命令的尾巴上加點東西,把圖形畫出來:

cat everytinginone.txt | grep ISF2010 | awk {n++; s+=$6; print NR, s/n} &> avg; gnuplot -p -e "plot avg with lines"

就得到這樣的圖:

這樣的命令並不很長,但確實是實踐中所用,避免了寫很多用完就扔的小程序。


兩個實用但不算太複雜的sample (Mac):

1. 統一更改某文件夾裹所有txt檔案: sed -i -e s/toDel/toAdd/g $(find . -name "*.txt")

2. Ping 所有host table裹的ip: grep -v "#" /etc/hosts | grep -oE "[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}" | sort | uniq | while read pinip ; do ping -c 1 "$pinip" &> /dev/null ;if [ $? -eq 0 ]; then echo "node $pinip is up" ; else echo "node $pinip is down"; fi ; done


這個問題好莫名其妙... 我可以寫幾個內部邏輯超級複雜的幾個小程序,但是調用極其容易(參數簡單)。

標準輸出當做後續參數用管道串起來執行... 複雜程度可以無上限。。。


剛剛寫的

find . -type f -exec sh -c "iconv -f GBK -t UTF-8 {} &> {}"

然後就gg了


講真,越來越不願意使用那麼多命令,再用*管道*串起來。

有些命令是常見的,有些是自己寫的或者少見,再加上各式各樣的參數,可讀性真的好么,時間久了恐怕自己都忘了。

不是太圖省事的,還真不如你提的就用 one-line awk。至少語法是一致的,懂awk的人一定懂。


推薦閱讀:

Windows 和 Unix 下的命令操作有什麼迷人之處?
PowerShell 與 Bash 相比,哪個更好?
如何善加利用 Mac 下的 Terminal ?
DOS的常用命令都有哪些?如何應用?
為什麼命令行界面(CLI)並未隨著命令行操作系統(如 DOS)的淘汰而消亡?

TAG:Linux | 文本數據分析 | 命令行界面CLI | 命令提示符cmd |