統計最常用10個命令的指令碼
統計最常用10個命令的指令碼
背景
某同學遇到個需求:
- 開發一個指令碼
- 可以統計出最長用的10個命令
- 輸出有4列, 序號(1~10), 數量(大~小), 佔比(大~小), 命令
思路
遇到這麼個問題, 自己又不會, 首先去百度了一下, 還真百度到了, 還是2個, 新測可用
統計本機最常用的10個命令(侵權通知刪除)
找出最常用的10條history命令的shell指令碼(侵權通知刪除)
效果如下
![image-20200911191932187](/Users/zhouweixin/Library/Application Support/typora-user-images/image-20200911191932187.png)
詳細分析
改寫後的指令碼
#!/bin/bash cat ~/.bash_history | awk '{ list[$1]++; } END { total=0; for(k in list){ total=total+list[k]; } for(k in list){ printf("%d\t%.4f\t%s\n", list[k], list[k]/total, k) } }' | sort -nrk 1 | head -n 10 | awk '{printf("%d\t%d\t%.4f\t%s\n", NR, $1, $2, $3)}'
相關知識點
1 如何顯示歷史命令
history
可以顯示所有的歷史命令, 直接在終端中輸入history
命令即可
查詢最新的n條命令, 返回的是不重複的n條件, 重複的不計算在內
history -n
$ history -3 2543 whatis history 2544 history 2545* history 2 2546* history -n 2 2547* history -2 2548* history -10 2549* history -3 2550* history -10 2551* history -20 2552* history -3 2553 hisgory -3
雖然返回的數量超過了3, 但是標*的表示為重複命令, 不重複的有3條
2 歷史命令的儲存
使用者在終端中操作的命令, 在關閉終端時會自動儲存到檔案中, 一般是.bash_history檔案, 最多儲存1000條
可以通過環境變數修改儲存檔案與儲存的最大條數
HISTFILE
: 表示命令儲存的檔名, 可以通過export HISTFILE=~/.cmd_file
修改
HISTFILESIZE
: 表示最大儲存的數量, 可以通過export HISTFILESIZE=2000
修改
$ echo $HISTFILE
/Users/zhouweixin/.bash_history
$ echo $HISTFILESIZE
1000
3 命令cat
查詢檔案的內容有許多命令, 功能描述如下表所述
命令 | 功能 | 備註 |
---|---|---|
cat | cat(英文全拼:concatenate)命令用於連線檔案並列印到標準輸出裝置上(如terminal) | |
more | 與cat功能相同, 區別在於可以一頁一頁的輸出, 空格翻頁 | |
less | less 與 more 類似, 使用 less 可以隨意瀏覽檔案, 而且 less 在檢視之前不會載入整個檔案 | |
head | head命令可用於檢視檔案的開頭部分的內容 | |
tail | tail 命令可用於檢視檔案尾部的內容 |
4 命令|
指令碼中用到了管理命令|
, 其功能是將左邊命令的輸出作為右邊命令的輸入
例如: 有一個檔名為go.mod, 內容如下
module zwx/learning/gin-demo-1
go 1.12
require (
code.byted.org/gin/ginex v1.6.11
github.com/cespare/xxhash v1.1.0 // indirect
github.com/gin-gonic/gin v1.6.3
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
)
經過前面的瞭解我們知道命令cat go.mod
可以把該檔案的內容列印到終端, 如下所示
$ cat go.mod
module zwx/learning/gin-demo-1
go 1.12
require (
code.byted.org/gin/ginex v1.6.11
github.com/cespare/xxhash v1.1.0 // indirect
github.com/gin-gonic/gin v1.6.3
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
)
假如我們並不想列印所有的內容, 僅想列印包含indirect行的內容, 則可以利用管道|
, 如下所示
$ cat go.mod | grep indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
管道|
把左側命令cat
的輸出重定向作為右側命令grep
的輸入(grep命令逐行判斷是否包含indirect內容)
類似連線多個命令符號有許多, 一定來看幾個
命令 | 功能 | 備註 |
---|---|---|
; | 連線多個命令, 順序執行, 成功失敗互不影響 | 示例: mkdir mydir; cd mydir |
> | 輸出重定向, 將左側命令的輸出重定向到右側檔案 | 示例: cat a.txt > b.txt |
< | 輸入重定向, 將右側檔案的內容作為左側命令的輸入 | |
& | 用於命令後, 表示後臺執行命令 | |
&& | 邏輯與, 只有左側命令為true, 右側命令才會執行 | |
|| | 邏輯或, 只有左側命令為false, 右側才會執行 |
5 命令awk
AWK 是一種處理文字檔案的語言,是一個強大的文字分析工具。
之所以叫 AWK 是因為其取了三位創始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字元。
使用詳情可參考
6 命令sort
sort命令用於將文字檔案內容加以排序, 以行為單位來排序
相關引數
- -b 忽略每行前面開始出的空格字元。
- -c 檢查檔案是否已經按照順序排序。
- -d 排序時,處理英文字母、數字及空格字元外,忽略其他的字元。
- -f 排序時,將小寫字母視為大寫字母。
- -i 排序時,除了040至176之間的ASCII字元外,忽略其他的字元。
- -m 將幾個排序好的檔案進行合併。
- -M 將前面3個字母依照月份的縮寫進行排序。
- -n 依照數值的大小排序。
- -u 意味著是唯一的(unique),輸出的結果是去完重了的。
- -o<輸出檔案> 將排序後的結果存入指定的檔案。
- -r 以相反的順序來排序。
- -t<分隔字元> 指定排序時所用的欄位分隔字元。
- +<起始欄位>-<結束欄位> 以指定的欄位來排序,範圍由起始欄位到結束欄位的前一欄位。
- --help 顯示幫助。
- --version 顯示版本資訊。