[Linux Shell学习系列十四]sed和awk-7.awk命令实例

D30

通过实例来学习如何将awk命令应用在shell脚本中。

 

1.使用awk编写字符统计工具

#统计文件中指定字符出现次数
$ cat letter_count.sh 
#!/bin/bash
#202006

INIT_TAB_AWK=""

count_case=0
FILE_PARSE=$1

E_PARAMERR=65

usage()
{
        echo "Usage: `basename $0` file letters" 2>&1
        exit $E_PARAMERR
}

if [ ! -f "$1" ]
then
        echo "$1: No such file." 2>&1
        usage
fi

if [ -z "$2" ]
then
        echo "$2: No letters specified." 2>&1
        usage
fi

shift

#遍历每个指定的字符
for letter in `echo $@`
do
        INIT_TAB_AWK="$INIT_TAB_AWK tab_search[${count_case}] = \"$letter\"; final_tab[${count_case}] = 0; "  #将要出现的字符保存在tab_search数组,将字符对应的数量保存在final_tab数组

        count_case=`expr $count_case + 1` 
done

#将文件内容通过管道传递给awk命令
cat $FILE_PARSE | awk "BEGIN { $INIT_TAB_AWK } \
{ split(\$0, tab, \"\"); \ #awk中的split命令将一行记录按照单个字符分隔并存放到数组tab中
for ( chara in tab ) { \ #遍历tab中的每个字符
for ( chara2 in tab_search ) { \ #遍历tab_search中的每个字符
if ( tab_search[chara2] == tab[chara] ) { final_tab[chara2]++ } } } } \ #如果字符匹配,则final_tab数组中该字符的数量加1
END { for ( chara in final_tab ) { print tab_search[chara] \" => \"  final_tab[chara] } } " #分别打印每个字符和对应的数量

exit $?
执行:

$ cat info.txt 
Linux - Sysadmin
Database - Oracle, MySQL etc.
Security - Firewall, Network, Online Security etc.
Cool - Websites

$ ./letter_count.sh info.txt  a W
a => 6
W => 1

 

2. 使用awk程序统计文件的总列数

#统计一个文件的总列数
$ cat column_totaler.sh 
#!/bin/bash
#202006

ARGS=2

E_WRONGARGS=65

column_number=$2 #读取脚本的第二个参数,即每行的列数

usage()
{
        echo "Usage: `basename $0` file letters" 2>&1
        exit $E_WRONGARGS
}

if [ $# -ne "$ARGS" ]
then
        usage
fi

if [ ! -f "$1" ]
then
        echo "$1: No such file." 2>&1
        usage
fi

#awk程序
awkscript={total += col_num} END { print total }

#awk命令:先把column_number的值赋给col_num,然后每读取一行都在total上增加col_num,最后打印total
echo awk -v col_num="$column_number" "$awkscript" "$1"
awk -v col_num="$column_number" "$awkscript" "$1"

exit 0
执行:

$ cat info.txt 
Linux - Sysadmin
Database - Oracle, MySQL etc.
Security - Firewall, Network, Online Security etc.
Cool - Websites

$ ./column_totaler.sh info.txt 3
awk -v col_num=3 {total += col_num} END { print total } info.txt
12
#共有四行,每行3列,共12

 

3. 使用awk自定义显示文件的属性信息

#自定义显示文件属性
$ cat fileinfo.sh 
#!/bin/bash
#202006

E_WRONGARGS=65

if [ -z "$1" ]
then
        echo "Usage: `basename $0` file_path"
        exit
fi

file=$1

if [ ! -e "$file" ]
then
        echo "$file does not exist."
        exit $E_WRONGARGS
fi

#打印文件的全路径+两个制表符+文件大小
ls -l $file | awk { print $9 "\t\tfile size: " $5 }

#需要设置whatis数据库后使用,未尝试
#whatis `basename $file`

echo 

exit 0
执行:

$ ./fileinfo.sh info.txt 
info.txt                file size: 114

#与初始的ls -l结果对比,文件名在$9,文件大小在¥5
$ ls -l info.txt 
-rw-rw-r--. 1 user1 user1 114 Jun 12 13:31 info.txt

 

4. 使用awk显示ASCII字符

D31

$ cat printAscII.sh 
#!/bin/bash
#202006

START=33
END=125

echo -e "\tDecimal\tHex\tCharacter"
echo -e "\t-------\t---\t---------"

for (( i=START; i<=END; i++))
do
        #对于awk中的printf语句,%d表示整数,%x表示十六进制格式,%c表示ASCII字符
        #%3d 表示输出3位整型数, 不够3位右对齐,%2x同理
        echo $i | awk {printf("\t%3d\t%2x\t%c\n", $1, $1, $1)}
done

exit 0

#执行:
$ ./printAscII.sh 
        Decimal Hex     Character
        ------- ---     ---------
         33     21      !
         34     22      "
         35     23      #
         36     24      $
         37     25      %
         38     26      &
         39     27               40     28      (
         41     29      )
         42     2a      *
         43     2b      +
         44     2c      ,
         45     2d      -
         46     2e      .
         47     2f      /
         48     30      0
         49     31      1
         50     32      2
         51     33      3
         52     34      4
         53     35      5
         54     36      6
         55     37      7
         56     38      8
         57     39      9
         58     3a      :
         59     3b      ;
         60     3c      <
         61     3d      =
         62     3e      >
         63     3f      ?
         64     40      @
         65     41      A
         66     42      B
         67     43      C
         68     44      D
         69     45      E
         70     46      F
         71     47      G
         72     48      H
         73     49      I
         74     4a      J
         75     4b      K
         76     4c      L
         77     4d      M
         78     4e      N
         79     4f      O
         80     50      P
         81     51      Q
         82     52      R
         83     53      S
         84     54      T
         85     55      U
         86     56      V
         87     57      W
         88     58      X
         89     59      Y
         90     5a      Z
         91     5b      [
         92     5c               93     5d      ]
         94     5e      ^
         95     5f      _
         96     60      `
         97     61      a
         98     62      b
         99     63      c
        100     64      d
        101     65      e
        102     66      f
        103     67      g
        104     68      h
        105     69      i
        106     6a      j
        107     6b      k
        108     6c      l
        109     6d      m
        110     6e      n
        111     6f      o
        112     70      p
        113     71      q
        114     72      r
        115     73      s
        116     74      t
        117     75      u
        118     76      v
        119     77      w
        120     78      x
        121     79      y
        122     7a      z
        123     7b      {
        124     7c      |
        125     7d      }

 

5. 使用awk获取进程号

$ cat findProcess.sh 
#!/bin/bash
#202006

ARGNO=1

E_WRONGARGS=65
E_BADPID=66
E_NOSUCHPROCESS=67
E_NOPERMISSION=68

PROCFILE=exe

if [ $# -ne $ARGNO ]
then
        echo "Usage: `basename $0` PID-number" >&2
        exit $E_WRONGARGS
fi

# 确认指定的PID
pidno=$( ps ax | grep $1 | awk { print $1 } | grep $1 )

#未找到指定的PID,则退出
if [ -z "$pidno" ]
then
        echo "No such process running."
        exit $E_NOSUCHPROCESS
fi

#检查文件的读权限
if [ ! -r "/proc/$1/$PROCFILE" ]
then
        echo "Process $1 running, but ..."
        echo "Can‘t get read permission on /proc/$1/$PROCFILE."
        exit $E_NOPERMISSION
fi

#检查软链接并通过awk获取第11列的字符串,即软链接指向的可执行文件的全路径
exe_file=$(ls -l /proc/$1/$PROCFILE| awk { print $11 } )

#输出结果
if [ -e "$exe_file" ]
then
        echo "Process #$1 invoked by $exe_file."
else
        echo "No such process running."
fi

exit 0

#执行:
$ ps -ef| grep bash
ntrade   22018 22017  0 08:39 pts/0    00:00:00 -bash

$ ./findProcess.sh 22018
Process #22018 invoked by /usr/bin/bash.

#如果是不存在的PID
$ ./findProcess.sh 22019
No such process running.

#如果是没有权限的PID
$ ./findProcess.sh 22013
Process 22013 running, but ...
Cant get read permission on /proc/22013/exe.

 

本节结束

 

[Linux Shell学习系列十四]sed和awk-7.awk命令实例

上一篇:Shell脚本


下一篇:在MAC下使用VSCode连接远程Linux服务器(无密)