概括awk函数

时间:2018-03-26 12:10:02

标签: bash shell

为了提高工作效率,我使用以下函数来了解我需要别名的函数,因为我最常使用它们:

function mu() {
    if [[ $# -eq 0 ]]; then
        history | awk '{CMD[$2]++;count++;}END { for (a in CMD)print CMD[a] " " CMD[a]/count*100 "% " a;}' | grep -v "./" | column -c3 -s " " -t | sort -nr | nl |  head -n10
    elif [[ $# -eq 1 ]]; then
        history | awk '$2=="'$1'"{CMD[$3]++;count++;}END { for (a in CMD)print CMD[a] " " CMD[a]/count*100 "% " a;}' | grep -v "./" | column -c3 -s " " -t | sort -nr | nl |  head -n10
    elif [[ $# -eq 2 ]]; then
        history | awk '$2=="'$1'"&&$3=="'$2'"{CMD[$4]++;count++;}END { for (a in CMD)print CMD[a] " " CMD[a]/count*100 "% " a;}' | grep -v "./" | column -c3 -s " " -t | sort -nr | nl |  head -n10
    fi
}

此函数使用0,1或2个参数,在函数作为输入的参数之后显示最常用的参数。

有没有办法让这个适用于任意数量的参数?

对于4和5个参数,命令应如下所示:

history | awk '$2=="'$1'"&&$3=="'$2'"&&$4=="'$3'"{CMD[$5]++;count++;}END { for (a in CMD)print CMD[a] " " CMD[a]/count*100 "% " a;}' | grep -v "./" | column -c3 -s " " -t | sort -nr | nl |  head -n10
history | awk '$2=="'$1'"&&$3=="'$2'"&&$4=="'$3'"&&$5=="'$4'"{CMD[$6]++;count++;}END { for (a in CMD)print CMD[a] " " CMD[a]/count*100 "% " a;}' | grep -v "./" | column -c3 -s " " -t | sort -nr | nl |  head -n10

基本上,每个参数都应添加另一个条件,例如&&$4=="'$3'",并在[$6]之后更改括号内的数字。

这是预期的输出:

mu
     1  1065  13,3861%    cd
     2  1007  12,6571%    ls
     3  761   9,56511%    vim
     4  755   9,48969%    docker-compose
     ...

mu ls                      
     1  823  81,7279%
     2  12   1,19166%    logs
     3  5    0,496524%   mnt
     ...

等等。

2 个答案:

答案 0 :(得分:1)

你可以这样做:

function mu() {
    history | awk -v input="$@" -v pos="$((2 + $#))" '( substr($0, index($0,$2)) ~ "^" input){CMD[$pos]++;count++} END{ for (a in CMD) print CMD[a] " " CMD[a]/count*100 "% " a}' | grep -v "./" | column -c3 -s " " -t | sort -nr | nl | head -n10
}

在这里,繁重的工作由-v input="$@" -v pos="$((2 + $#))"( substr($0, index($0,$2)) ~ "^" input)完成:我们将参数数组转换为字符串input。然后我们将它与历史命令的开头进行比较。如果匹配,我们使用pos变量来确定要显示的字段。

对于zsh

旁注:,只需替换pos="$((4 + $#))"index($0,$4)即可获得相同的结果。

答案 1 :(得分:1)

如果你不介意使用perl,

perl开关:

  • -n喜欢sed循环输入而不打印
  • -a autosplit,进入@F数组


mu() {
  history | 
  perl -ane '
    BEGIN {
      @a = @ARGV;   # read parameters to @a
      @ARGV = ();   # clear parameters to avoid reading form file
    }
    $F[$_+1] eq $a[$_] or next LINE for 0..$#a; # loop over parameters check are equal to line fields otherwise continue with next line
    ++$H{$F[@a+1]};      # increment hash value whose key is field after last parameter
    ++$tot;              # increment total
    END {
      @r = sort { $H{$b} <=> $H{$a} }  # numeric sort over values
        keys %H;
      if (@r>10) {
         @r = @r[0..9]
      }
      printf "%s\t%.2f%%\t%s\n", $H{$_}, 100*$H{$_}/$tot, $_ for @r
    }
  ' "$@"    # pass parameter arguments
}