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 ... Can‘t get read permission on /proc/22013/exe.
本节结束