1. 程式人生 > 實用技巧 >統計最常用10個命令的指令碼

統計最常用10個命令的指令碼

統計最常用10個命令的指令碼

背景

某同學遇到個需求:

  1. 開發一個指令碼
  2. 可以統計出最長用的10個命令
  3. 輸出有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 的首字元。

使用詳情可參考

Linux awk 命令

6 命令sort

sort命令用於將文字檔案內容加以排序, 以行為單位來排序

相關引數

  • -b 忽略每行前面開始出的空格字元。
  • -c 檢查檔案是否已經按照順序排序。
  • -d 排序時,處理英文字母、數字及空格字元外,忽略其他的字元。
  • -f 排序時,將小寫字母視為大寫字母。
  • -i 排序時,除了040至176之間的ASCII字元外,忽略其他的字元。
  • -m 將幾個排序好的檔案進行合併。
  • -M 將前面3個字母依照月份的縮寫進行排序。
  • -n 依照數值的大小排序。
  • -u 意味著是唯一的(unique),輸出的結果是去完重了的。
  • -o<輸出檔案> 將排序後的結果存入指定的檔案。
  • -r 以相反的順序來排序。
  • -t<分隔字元> 指定排序時所用的欄位分隔字元。
  • +<起始欄位>-<結束欄位> 以指定的欄位來排序,範圍由起始欄位到結束欄位的前一欄位。
  • --help 顯示幫助。
  • --version 顯示版本資訊。

參考

  1. 統計本機最常用的10個命令
  2. 找出最常用的10條history命令的shell指令碼
  3. history命令
  4. Linux下有趣的命令
  5. Linux sort命令
  6. Linux awk 命令