Shell 编程(六):文本三剑客之 awk(二)

简介: awk 是一个文本处理工具,通常用于处理数据并生成结果报告,awk的命名是它的创始人 Alfred Aho、 Peter Weinberger 和 Brian Kernighan 姓氏的首个字母组成的。

匹配的两种用法

RegExp

  1. 匹配 /etc/passwd 文件行中含有 root 字符串的所有行
> awk '/root/{print $0}' passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin


  1. 匹配 /etc/passwd 文件行中以 yarn 开头的所有行
> awk '/^yarn/{print $0}' passwd

运算符匹配

关系运算符 含义
< 小于
> 大于
<= 小于等于
>= 大于等于
== 等于
!= 不等于
~ 匹配正则表达式
!~ 不匹配正则表达式
  1. 以:为分隔符,匹配 /etc/passwd 文件中第 3 个字段小于 50 的所有行信息
> awk 'BEGIN{FS=":"}$3<50{print $0}' passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nscd:x:28:28:NSCD Daemon:/:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin


  1. 以:为分隔符,匹配 /etc/passwd 文件中第 7 个字段不为 /bin/bash 的所有行信息
> awk 'BEGIN{FS=":"}$7!="/bin/bash"{print $0}' passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nolog
...


布尔运算符匹配

布尔运算符 含义
||
&&
  1. 以:为分隔符,匹配 /etc/passwd 文件中包含 hdfs 或 yarn 的所有行信息
> awk 'BEGIN{FS=":"} hdfs|| yarn {print $0}' passwd


  1. 以:为分隔符,匹配 /etc/passwd 文件中第 3 个字段小于 50 并且第 4 个字段大于 50 的所行信息
> awk 'BEGIN{FS=":"}$3<50 && $4>50{print $0}' passwd
games:x:12:100:games:/usr/games:/sbin/nologin


动作中的表达式用法

运算符 含义
+
-
*
/
%
^或** 乘方
++x 在返回 x 变量之前,x 变量加1
x++ 在返回 x 变量之后,x 变量加1
  1. 使用 awk 计算 /etc/services 中的空白行数量
> awk 'BEGIN{count=0}/^$/{count++;}END{print count}' services 
20


  1. 计算学生课程分数平均值,学生课程文件内容如下:
> cat student.txt 
allen 80 90 87 91
mike  78 86 93 96
Kobe  66 92 82 78
Jerry 98 74 66 54
wang  87 21 100 43
> awk 'BEGIN{printf "%-10s %-10s %-10s %-10s %-10s %-10s \n","name","chinese","math","english","computer","avg"}{avg=($2+$3+$4+$5)/4;printf "%-10s %-10d %-10d %-10d %-10d %-10d \n",$1,$2,$3,$4,$5,avg}' student.txt
name       chinese    math       english    computer   avg        
allen      80         90         87         91         87         
mike       78         86         93         96         88         
Kobe       66         92         82         78         79         
Jerry      98         74         66         54         73         
wang       87         21         100        43         62


动作中的条件及循环语句

条件语句

if (condition)
    action-1
else
    action-2


  1. 以:为分隔符,只打印 /etc/passwd 中第 3 个字段的数值在 50-100 范围内的行信息
> awk 'BEGIN{FS=":"}$3>50 && $3<100{print $0}' passwd
dbus:x:81:81:System message bus:/:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin


  1. 计算下列每个同学的平均分数,并且只打印平均分数大于90的同学姓名和分数信息
> cat student.txt
allen 80 90 87 91
mike  78 86 93 96
Kobe  66 92 82 78
Jerry 98 74 66 54
wang  87 21 100 43
> awk 'BEGIN{printf "%-10s %-10s %-10s %-10s %-10s %-10s \n","name","chinese","math","english","computer","avg"}{avg=($2+$3+$4+$5)/4;if(avg>90)printf "%-10s %-10d %-10d %-10d %-10d %-10d \n",$1,$2,$3,$4,$5,avg}' student.txt


循环语句

for (initialisation; condition; increment/decrement)
    action
while (condition)
    action
do(
)while()


  1. 计算1+2+3+4+…+100的和,请使用while、 do while、 for三种循环方式实现(我只写for了)
> awk 'BEGIN{sum=0;for(i=0;i<=100;i++)sum+=i;print sum}'
5050


字符串函数

函数名 解释 函数返回值
length(str) 计算字符串长度 整数长度值
index(str1,str2) 在 str1 中查找 str2 的位置 返回值为位置索引,从 1 计数
tolower(str) 转换为小写 转换后的小写字符串
toupper(str) 转换为大写 转换后的大写字符串
substr(str,m,n) 从 str 的 m 个字符开始,截取 n 位 截取后的子串
split(str,array,fs) 按 fs 切割字符串,结果保存 array 切割后的子串的个数
match(str,RE) 在 str 中按照 RE 查找,返回位置 返回索引位置
sub(RE,RepStr,str) 在 str 中搜索符合 RE 的字串,将其替换为 RepStr;(只替换第一个) 替换的个数
gsub(RE,RepStr,str) 在 str 中搜索符合 RE 的字串,将其替换为 RepStr;(替换所有) 替换的个数
  1. 以:为分隔符,返回 /etc/passwd 中每行中每个字段的长度
> awk '{print length($0)}' passwd
31
32
39
36
40
31
44
32
46
44
...


  1. 搜索字符串“I have a dream“中出现“ea“字符串的位置
> awk 'BEGIN{str="I have a dream";print index(str,"ea")}'
12


  1. 将字符串“Hadoop is a bigdata Framawork“全部转换为小写
> awk 'BEGIN{str="Hadoop is a bigdata Framawork";print tolower(str)}'
hadoop is a bigdata framawork


  1. 将字符串“Hadoop is a biadata Framawork“全部转换为大写
> awk 'BEGIN{str="Hadoop is a bigdata Framawork";print toupper(str)}'
HADOOP IS A BIGDATA FRAMAWORK


常用选项

选项 解释
-v 参数传递
-f 指定脚本文件
-F 指定分割符(FS)
-V 查看 awk 的版本号

数组用法

shell 中数组的用法:

array=("百度" "阿里" "腾讯")
功能 命令
打印元素 echo ${array[2]}
打印元素个数 echo ${#array[@]}
打印元素长度 echo ${#array[3]}
给元素赋值 array[1]=”字节跳动”
删除元素 unset array[2];unset array;
分片访问 echo ${array[@]: 1:3}
元素内容替换 $array [@/e/E]
数组的遍历 for a in ${array[0]}
do
 echo $a
done

awk 中数组的用法:

array[index]=value
功能 命令
创建数组 array[1]=”hello”
删除数组元素 delete array[1]
多维数组 array[“0,0”] = 100;
array[“0,1”] = 200;
array[“0,2”] = 300;
array[“1,0”] = 400;
array[“1,1”] = 500;
array[“1,2”] = 600;
  1. 统计主机上所有的 TCP 连接状态数,按照每个 TCP 状态分类
> netstat -an | grep tcp| awk '{array[$6]++}END{ for (a in array) print a,array[a]}'
LISTEN 21
SYN_RECV 1
ESTABLISHED 4
TIME_WAIT 2


  1. 计算横向数据综合,计算纵向数据总和
> cat student.txt 
allen 80 90 87 91
mike  78 86 93 96
Kobe  66 92 82 78
Jerry 98 74 66 54
wang  87 21 100 43
> awk 'BEGIN{printf "%-10s %-10s %-10s %-10s %-10s %-10s \n","name","chinese","math","english","computer","total"}{total=$2+$3+$4+$5;totol_count+=total;chinese_count+=$2;math_count+=$3;english_count+=$4;computer_count+=$5;printf "%-10s %-10d %-10d %-10d %-10d %-10d \n",$1,$2,$3,$4,$5,total}END{printf "%-10s %-10d %-10d %-10d %-10d %-10d \n","total",chinese_count,math_count,english_count,computer_count,totol_count}' student.txt
name       chinese    math       english    computer   total      
allen      80         90         87         91         348        
mike       78         86         93         96         353        
Kobe       66         92         82         78         318        
Jerry      98         74         66         54         292        
wang       87         21         100        43         251        
total      409        363        428        362        1562


参考 & 引用

Linux awk 命令 | 菜鸟教程

    目录
    相关文章
    |
    24天前
    |
    存储 Unix Shell
    shell脚本编程基础
    【9月更文挑战第4天】
    35 12
    |
    23天前
    |
    Shell Linux
    Shell 编程 编写hello word
    Shell 编写hello word
    40 5
    |
    1月前
    |
    Shell KVM 虚拟化
    Shell 数组编程
    【8月更文挑战第22天】 Shell 数组编程
    42 10
    |
    1月前
    |
    Shell 数据处理 C++
    【震撼揭秘】Python正则VS Shell正则:一场跨越编程边界的史诗级对决!你绝不能错过的精彩较量,带你领略文本处理的极致魅力!
    【8月更文挑战第19天】正则表达式是文本处理的强大工具,在Python与Shell中有广泛应用。两者虽语法各异,但仍共享许多基本元素,如`.`、`*`及`[]`等。Python通过`re`模块支持丰富的功能,如非捕获组及命名捕获组;而Shell则依赖`grep`、`sed`和`awk`等命令实现类似效果。尽管Python提供了更高级的特性和函数,Shell在处理文本文件方面仍有其独特优势。选择合适工具需根据具体需求和个人偏好决定。
    27 1
    |
    1月前
    |
    监控 Shell Linux
    探索Linux操作系统下的Shell编程之魅力
    【8月更文挑战第4天】本文旨在通过一系列精心设计的示例和分析,揭示在Linux环境下进行Shell编程的独特之处及其强大功能。我们将从基础语法入手,逐步深入到脚本的编写与执行,最终通过实际代码案例展现Shell编程在日常系统管理和自动化任务中的应用价值。文章不仅适合初学者构建扎实的基础,同时也为有一定经验的开发者提供进阶技巧。
    42 11
    |
    9月前
    |
    Shell 数据处理 Perl
    shell脚本里的三剑客之一awk
    shell脚本里的三剑客之一awk
    80 2
    |
    自然语言处理 Shell Perl
    Shell脚本中使用awk进行空格分词
    Shell脚本中使用awk进行空格分词
    200 0
    |
    Shell Perl
    shell脚本之awk命令(二)
    1、工作原理 2、AWK格式 3、按行输入文本 4、按字段输入文本 5、通过管道符号,双引号调用shell命令
    shell脚本之awk命令(二)
    |
    Shell Perl
    shell脚本之awk命令(一)
    1、工作原理 2、AWK格式 3、按行输入文本 4、按字段输入文本 5、通过管道符号,双引号调用shell命令
    shell脚本之awk命令(一)
    |
    自然语言处理 Shell Perl
    Shell脚本中使用awk进行空格分词
    Shell脚本中使用awk进行空格分词
    205 0