自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

沒想到 Shell 命令竟然還能這么玩?

開發(fā) 開發(fā)工具
本文是一個命令行工具的綜合應用,將用一個具體的例子來闡述如何用 Shell 來進行高效地數(shù)據(jù)統(tǒng)計和分析。最近北京又開始了新一批積分落戶的填報工作,恰好這篇文章用 shell 來對首批北京積分落戶同學進行 "大數(shù)據(jù)"分析。

[[337756]]

正文開始

在前面的這篇文章中 —— 優(yōu)秀的程序員是如何利用工具來提升工作效率的?,石頭介紹了可以提高程序猿工作效率的一些軟件和工具及相關配置。文中提到了, 程序猿應該了解一些常見的命令行工具來提高效率。

本文是一個命令行工具的綜合應用,將用一個具體的例子來闡述如何用 Shell 來進行高效地數(shù)據(jù)統(tǒng)計和分析。最近北京又開始了新一批積分落戶的填報工作,恰好這篇文章用 shell 來對首批北京積分落戶同學進行 "大數(shù)據(jù)"分析。

現(xiàn)如今到處都是各種"大數(shù)據(jù)",本文分析對象也就是首批積分落戶的6000多條數(shù)據(jù)而已,顯然不能算什么大數(shù)據(jù)。

印象中,我記得當初該官網(wǎng)的這6000多條數(shù)據(jù)也是一次性就能wget下來的(后端估計沒做限制,可能稍微調(diào)整下接口的分頁參數(shù)之類不需要嚴格按照各種分頁多次下載)。(注:本文舊文重新整理發(fā)送。)

問題描述

輸入是 json數(shù)據(jù),格式化之后的 json 數(shù)據(jù)主題結構如下所示,rows為數(shù)組,數(shù)組中元素所代表的 object 即描述了獲得北京戶口的同學的各種屬性:例如分數(shù)、排名、身份證號(后四位打碼了)、公司等等信息。為了方便大家練習對數(shù)據(jù)進行試驗,我將文中的數(shù)據(jù)附在這里(https://www.tanglei.name/resources/use-shell-to-analysis-the-first-people-of-getting-residence-of-beijing-by-score/jifenluohu.json.gz)。

  1. "rows": [ 
  2.     "id": 62981, 
  3.     "idCard""32092219721222****"
  4.     "idCardSHA""9ef70bde894959a4e4a1d1b2b9592b470294f9e4012a8cf480319665d1a7c1c6"
  5.     "insertTime": 1539518353000, 
  6.     "integralQualified": 1, 
  7.     "internetAnnual": { 
  8.         "annual": 2018, 
  9.         "id": 43, 
  10.         "insertTime": 1539518353000, 
  11.         "publicityEnd": 1540224000000, 
  12.         "publicityStart": 1539591600000, 
  13.         "publishResultEndDate": 1541679300000, 
  14.         "publishResultStartDate": 1539591600000, 
  15.         "publishResultStatus": 1, 
  16.         "score": 90.75, 
  17.         "status": 1 
  18.     }, 
  19.     "md5Code""54e9ff7ce0b004f7141b157f8afc66db"
  20.     "name""楊效豐"
  21.     "pxid": 1, 
  22.     "ranking": 1, 
  23.     "s1": 51, 
  24.     "s10": 0, 
  25.     "s2": 12.59, 
  26.     "s3": 15, 
  27.     "s4": 0, 
  28.     "s5": 4, 
  29.     "s6": 0, 
  30.     "s7": 20, 
  31.     "s8": 20, 
  32.     "s9": 0, 
  33.     "score": 122.59, 
  34.     "unit""北京利德華福電氣技術有限公司" 
  35. }, 

拿到這個文件,比如希望你用最快的方法獲得以下信息,你將會怎么做?

  • 獲取取得戶口名額最多的top10公司
  • 獲取取得戶口名額的人中姓氏最多的
  • 獲取戶口名字中叫啥名最流行
  • 獲取年齡分布
  • 獲取取得戶口的同學戶籍地top10
  • 生肖/星座/生日...

當然,方法有很多,比如熟悉各種編程語言的,例如 python, php, java 等等寫個簡單的腳本程序,也能比較快獲取答案?;蛘甙严鄳臄?shù)據(jù)提取出來,放到 excel 中也可以。

如果你對 Shell 很熟悉,那真的是分分鐘,應該是秒秒鐘就能獲取答案。就算用 Shell 來實現(xiàn),不同的人可能也有不同的寫法,后面我就列舉其中的一種來解決這些問題。

本文不對 Shell 具體每個命令做過多的解釋,不熟悉的同學可以直接 man $cmd 或者 $cmd --help 等等查看。

之前我也寫過一篇名叫 Shell 助力開發(fā)效率提升 的文章,算是給常用的命令的常用參數(shù)做了一個解釋和示例,有興趣的同學可以前往查閱。

問題解答

獲取取得戶口名額最多的top10公司

看看想通過積分落戶,最好是進哪些公司,哈哈。

"unit": "北京利德華福電氣技術有限公司"

先通過 grep 得到包含公司名字的一行,然后通過 ":" 分割 cut 取第2列得到公司名字,對結果進行sort排序進行去重uniq統(tǒng)計得到重復次數(shù),次時結果為重復次數(shù) 公司名,再對第一列-k 1重復數(shù)字進行按照數(shù)字排序逆序-nr 即 sort -nr -k 1,最后取結果的前10行 head -n 10。

  1. ➜  積分落戶  > grep 'unit' jifenluohu.json| cut -f2 -d: | sort | uniq -c | sort -nr -k 1 | head -n 10 
  2.  137  "北京華為數(shù)字技術有限公司" 
  3.   73  "中央電視臺" 
  4.   57  "北京首鋼建設集團有限公司" 
  5.   55  "百度在線網(wǎng)絡技術(北京)有限公司" 
  6.   48  "聯(lián)想(北京)有限公司" 
  7.   40  "北京外企人力資源服務有限公司" 
  8.   40  "中國民生銀行股份有限公司" 
  9.   39  "國際商業(yè)機器(中國)投資有限公司" 
  10.   29  "中國國際技術智力合作有限公司" 
  11.   27  "華為技術有限公司北京研究所" 

獲取取得戶口名額的人中姓氏最多的

看看想通過積分落戶,最好是姓啥,哈哈。

"name": "楊效豐",

套路跟之前差不多的,我這邊就不特別指出了。

下面shell實際上是取到這行后,將真正表示名字之前的所有字符都刪除,就只剩下名字開頭了,取行首第一個字符cut -c 1即得到姓,再按照之前的套路就能拿到了。

其實用什么sed替換冗余的字符都是多余的,因為json的格式都是良好的,可以直接通過 cut -c ? 取姓這個字符即可。

也不用挨個去數(shù)到底是第幾個字符,直接 copy出來,然后 echo -n $paste | wc -c 就能數(shù)到第幾個字符了。

看結果還是姓 "張, 王" 之類的最有戲。??

  1. # 或者 grep '"name":' jifenluohu.json| sed 's|"name": "||g' | sed 's|[[:space:]]||g' | cut -c 1 | sort | uniq -c | sort -nr -k 1 | head -n 10 
  2. ➜  積分落戶  > grep '"name":' jifenluohu.json| sed 's|"name": "||g' | sed 's| ||g' | cut -c 1 | sort | uniq -c | sort -nr -k 1 | head -n 10 
  3.  541 張 
  4.  531 王 
  5.  462 李 
  6.  376 劉 
  7.  205 陳 
  8.  193 楊 
  9.  166 趙 
  10.  132 孫 
  11.   95 郭 
  12.   95 徐 

獲取戶口名字中叫啥名最流行

套路差不多,不做過多解釋了。

  1. ➜  積分落戶  > grep '"name":' jifenluohu.json| sed 's|"name": "||g' | sed 's|[[:space:]]||g' | cut -c 2-4 | sort | uniq -c | sort -nr -k 1 | head -n 10 
  2.   51 偉", 
  3.   39 靜", 
  4.   38 濤", 
  5.   36 勇", 
  6.   36 軍", 
  7.   32 敏", 
  8.   31 穎", 
  9.   30 鵬", 
  10.   28 杰", 
  11.   28 峰", 
  12. # 取名字, 必須包含2個字 
  13. ➜  積分落戶  > grep '"name":' jifenluohu.json| sed 's|"name": "||g' | sed 's|[[:space:]]||g' | cut -c 2-3 | sed  '/"/d' | sort | uniq -c | sort -nr -k 1 | head -n 10 
  14.   19 海濤 
  15.   19 曉東 
  16.   12 志強 
  17.   11 海燕 
  18.   11 永強 
  19.   11 建華 
  20.   10 雪梅 
  21.    9 海龍 
  22.    9 麗娜 
  23.    8 洪濤 

作為碼農(nóng),必須得養(yǎng)成對自己得到結果進行自測的習慣,所以如果對自己的結果不夠自信,可以正向去計算一下最終的結果。

例如可以簡單grep一下進行驗證,叫 "海濤" 的是不是19個。

  1. ➜  積分落戶  > grep '海濤' jifenluohu.json | wc -l 
  2.       19   

獲取年齡分布

思路是截取身份證中號碼中代表出生年的4位數(shù),然后拿當前年份2019減出生年得到年齡,后面的套路又一樣了。

bc 一個簡單的計算器程序,了解下?

  1. ➜  shell-train  > echo "3+2-5/5" | bc 
  2. ➜  shell-train  > echo "3.141592*5-4" | bc 
  3. 11.707960 
  4. #思路1: `cut -c 9-12` 獲取出生年, 拼接表達式 `2019-出生年` 得到年齡. 
  5. ➜  積分落戶  > grep '"idCard":' jifenluohu.json| cut -f2 -d: | cut -c 9-12 | xargs -n1 echo 2019 -|bc | sort | uniq -c 
  6.    3 34 
  7.   13 35 
  8.   39 36 
  9.  109 37 
  10.  162 38 
  11.  302 39 
  12.  507 40 
  13.  773 41 
  14.  799 42 
  15.  813 43 
  16.  757 44 
  17.  586 45 
  18.  507 46 
  19.  378 47 
  20.  238 48 
  21.    4 49 
  22.    9 50 
  23.    1 51 
  24.    4 52 
  25.    3 53 
  26.    2 54 
  27.    5 55 
  28.    1 56 
  29.    1 58 
  30.    1 59 
  31.    1 60 
  32.    1 61 

awk 是個好東西, 多練練.

  1. # 拿到出生年后, 直接通過 awk 計算結果輸出 
  2. ➜  積分落戶  > grep '"idCard":' jifenluohu.json| cut -f2 -d: | cut -c 9-12 |awk '{print 2019-$1}' | sort | uniq -c 
  3.    3 34 
  4.   13 35 
  5.   39 36 
  6.  109 37 
  7.  162 38 
  8.  302 39 
  9.  507 40 
  10.  773 41 
  11.  799 42 
  12.  813 43 
  13.  757 44 
  14.  586 45 
  15.  507 46 
  16.  378 47 
  17.  238 48 
  18.    4 49 
  19.    9 50 
  20.    1 51 
  21.    4 52 
  22.    3 53 
  23.    2 54 
  24.    5 55 
  25.    1 56 
  26.    1 58 
  27.    1 59 
  28.    1 60 
  29.    1 61    

獲取取得戶口的同學戶籍地top10

有時候,我們在寫Shell的時候,為了debug方便,可能會將一些中間結果緩存到文件中,后續(xù)以該文件為基礎進行后續(xù)的計算。

比如先拿到top10的身份證中代表的戶籍地的四位編碼,這里需要借助另外的一個表示身份證戶籍地的編碼來進行對應。

借此機會解釋下 join 這個命令。

  1. # 身份證前4位為例, 拿到戶籍地 
  2. grep '"idCard":' jifenluohu.json| cut -f2 -d: | cut -c 3-6 | sort | uniq -c | sort -nr -k 1 >topcity.code 
  3. # 城市列表 
  4. ➜  積分落戶  > more city.csv 
  5. 11,北京市 
  6. 1101,北京市市轄區(qū) 
  7. 110101,北京市東城區(qū) 
  8. 110102,北京市西城區(qū) 
  9. 110103,北京市崇文區(qū) 
  10. 110104,北京市宣武區(qū) 
  11. 110105,北京市朝陽區(qū) 
  12. # grep -E '^[0-9]{4},' city.csv | sed 's|,| |g' > city.code4 
  13. ➜ shell-train  > head -n 2 city.code4 
  14. 1101 北京市市轄區(qū) 
  15. 1102 北京市市轄縣 
  16. ➜ shell-train  > head -n 2 topcity.code 
  17.  197 1201 
  18.  156 1302 
  19. ➜ shell-train  > join 
  20. usage: join [-a fileno | -v fileno ] [-e string] [-1 field] [-2 field] 
  21.             [-o list] [-t char] file1 file2 

其實,join 就類似sql中的 ...inner join ...on ..., -t 分隔符,默認為空格或tab。

  1. # 未排序, 所以沒有將所有的導出(join需要排序) 
  2. ➜ shell-train  > join -1 1 -2 2 city.code4 topcity.code 
  3. 1201 天津市市轄區(qū) 197 
  4. 1302 河北省唐山市 156 
  5. 2301 黑龍江哈爾濱市 123 
  6. 4201 湖北省武漢市 118 
  7. 6101 陜西省西安市 100 
  8. 6201 甘肅省蘭州市 59 
  9. 6501 新疆烏魯木齊市 29 
  10. 6523 新疆昌吉回族自治州 11 

一定需要將結果輸出到文件,然后再進行嗎?

其實也不一定。用管道的方式 | 可以將上一個命令的輸出結果作為下一個命令的輸入,可以通過 <(command) 的方式,將command 的輸出作為一個文件輸入。

  1. # 需要排序 
  2. ➜ shell-train  > join -1 1 -2 2 city.code4 <(head -n 10 topcity.code | sort -k 2) 
  3. 1201 天津市市轄區(qū) 197 
  4. 1301 河北省石家莊市 114 
  5. 1302 河北省唐山市 156 
  6. 1324 河北省保定地區(qū) 103 
  7. 1501 內(nèi)蒙古呼和浩特市 88 
  8. 2101 遼寧省沈陽市 109 
  9. 2201 吉林省長春市&nbsp;113 
  10. 2301 黑龍江哈爾濱市 123 
  11. 4201 湖北省武漢市 118 
  12. 6101 陜西省西安市 100 

舉個例子paste用來將兩個文件按列合并在一起:

  1. ➜  shell-train  > cat paste.f1 
  2. hello, i am 
  3. world, you are 
  4. ➜  shell-train  > cat paste.f2 
  5. tanglei, wechat is: tangleithu 
  6. ?, hahaha 
  7. ➜  shell-train  > paste paste.f1 paste.f2 
  8. hello, i am tanglei, wechat is: tangleithu 
  9. world, you are ?, hahaha 

以上用paste將兩個文件合并在一起了,實際上通過 <(cmd)的方式,可以不借助外部文件也能做到。

方法如下:

  1. ➜  shell-train  > paste <(echo "hello, i am \nworld, you are") <(echo "tanglei, wechat is: tangleithu\n?, hahaha"
  2. hello, i am  tanglei, wechat is: tangleithu 
  3. world, you are ?, hahaha 

本文轉載自微信公眾號「程序猿石頭」,可以通過以下二維碼關注。轉載本文請聯(lián)系程序猿石頭公眾號。

 

責任編輯:武曉燕 來源: 程序猿石頭
相關推薦

2021-01-27 18:13:35

日志nginx信息

2023-02-26 00:00:02

字符串分割String

2017-02-09 17:00:00

iOSSwiftKVC

2021-11-29 05:37:24

Windows Def操作系統(tǒng)微軟

2020-12-31 06:12:38

Siri Windows電腦

2015-07-15 13:00:31

英特爾開源

2023-12-26 15:10:00

處理二進制文件

2021-02-25 17:58:26

Python 開發(fā)編程語言

2017-12-12 11:09:39

顯卡散熱CPU

2019-12-09 10:13:20

HashMap選擇容量

2021-03-18 09:06:17

函數(shù)MainJava

2021-02-21 17:14:27

程序員技能開發(fā)者

2018-05-02 09:38:02

程序員代碼互聯(lián)網(wǎng)

2020-05-09 16:45:56

ping命令Linux

2022-11-29 09:12:12

硬件技術拼圖

2019-12-16 09:10:46

碼農(nóng)熊貓員工

2016-09-01 13:54:23

Google太空電梯懸滑板

2018-01-26 23:23:23

JDBC MySQL數(shù)據(jù)庫

2017-12-26 15:41:26

2021-08-31 09:35:01

TCPIP漏洞
點贊
收藏

51CTO技術棧公眾號