awk讲解步骤
来源:互联网 发布:淘宝自动核对地址 编辑:程序博客网 时间:2024/06/09 23:53
awk
语法
awk [options] ‘commands’ files
option
-F 定义字段分隔符,默认的分隔符是连续的空格或制表符
使用option中的-F参数定义间隔符号
用
NF变量表示当前记录的字段数
-v 定义变量并赋值 也可以借用次方式从shell变量中引入
command 读前处理 行处理 读后处理 1.读前处理 BEGIN{awk_cmd1;awk_cmd2} 2.行处理:定址 命令 定址方法: 正则,变量,比较和关系运算 正则需要用//包围起来 ^ 行首 $ 行尾 . 除了换行符以外的任意单个字符 * 前导字符的零个或多个 .* 所有字符 [] 字符组内的任一字符 [^] 对字符组内的每个字符取反(不匹配字符组内的每个字符) ^[^] 非字符组内的字符开头的行 [a-z] 小写字母 [A-Z] 大写字母 [a-Z] 小写和大写字母 [0-9] 数字 \< 单词头 单词一般以空格或特殊字符做分隔,连续的字符串被当做单词 \> 单词尾 扩展正则 加 -r 参数 或转义 sed -n '/roo\?/p' /etc/passwd sed -rn '/roo?/p' /etc/passwd ? 前导字符零个或一个 + 前导字符一个或多个 abc|def abc或def a(bc|de)f abcf 或 adef x\{m\} x出现m次 x\{m,\} x出现m次至多次(至少m次) x\{m,n\} x出现m次至n次 NR变量定址 NR 表示AWK读入的行数 FNR表示读入行所在文件中的行数 # awk '{print NR,FNR,$1}' file1 file2 1 1 aaaaa 2 2 bbbbb 3 3 ccccc 4 1 dddddd 5 2 eeeeee 6 3 ffffff # 逻辑运算 可直接引用域进行运算 == >= <= != > < ~ !~ # awk 'NR==1 {print}' /etc/passwd root:x:0:0:root:/root:/bin/bash # 3.命令 {print $0} 4.读后处理 END {awk_cmd1;awk_cmd2;}
AWK变量
NR 当前记录的个数(全部文件连接后的统计)
FNR 当前记录的个数(仅为当前文件的统计,非全部)
FS 字段分隔符 默认为连续空格或制表符,可以使用多个不同的符号做分隔符 -F[:/]
OFS 输出字符的分隔符 默认是空格
# awk -F: ‘OFS=”=====” {print
root=====x
NF 当前读入行的字段个数
ORS 输出记录分隔符 默认是换行
# awk -F: ‘ORS=”=====” {print
root x=====bin x=====
FILENAME 当前文件名
引用shell变量的方法
# a=root
# awk -v var=
或者 把整个命令拆开传递,让shell变量外露,
# awk -F: ‘1 == "'a’” {print0}’ /etc/passwd
# a=NF
# awk -F: ‘{print
操作符
赋值
= += -= /= *=
逻辑与 逻辑或 逻辑非
&& || !
匹配正则或不匹配,正则需要用 /正则/ 包围住
~ !~
关系 比较字符串时要把字符串用双引号引起来
< <= > >= != ==
字段引用
运算符
+ - * / % ++ –
转义序列
\ \自身
$ 转义$
\t 制表符
\b 退格符
\r 回车符
\n 换行符
\c 取消换行
试做
打印uid在30~40范围内的用户名。
打印第5-10行的行号和用户名
打印奇数行
打印偶数行
打印字段数大于5的行
打印UID不等于GID的用户名
打印没有指定shell的用户
打印1..1000以内的7的倍数和包含7的数
统计出每种shell的使用人数,输出格式如下
1
1 /bin/sync
6 /bin/bash
31 /sbin/nologin
1 /sbin/halt
1 /sbin/shutdown
把你主机的所有IP地址提取出来
流程控制
分支结构
if (条件) 动作 若有多个动作,则要用大括号将动作体包含起来 if (条件) {动作1;动作2}# awk -F: '{if ($1 == "root") print $1}' /etc/passwdroot# # awk -F: '{if ($1 == "root") {print $1;print $6}}' /etc/passwdroot/root#if (条件1) 动作1else 动作2# awk -F: '{if ($1 == "root"){print $1}else print $6}' /etc/passwd# awk -F: '{if ($1 == "root") print $1;else print $6}' /etc/passwd上面两个命令是等价的,要么用分号隔开,表示第一个动作体的结束,要么将动作体用大括号定位范围if (条件 1) 动作1else if(条件 2) 动作2else if(条件 3) 动作3else 动作4# awk -F: '{if ($1 == "root") print $1;else if ($1 == "seker") print $6;else if ($1 == "zorro") print $7;else print NR}' /etc/passwdroot23...33/home/seker/bin/bash36条件 ? 动作1 : 动作2expr?action1:action2# awk -F: 'var=($3 >= 500)?$1:"system_user" {print $1"\t"$3"\t"var}' /etc/passwd# awk -F: '{print ($3>500?$1:$2)}' /etc/passwd
试做
将系统用户按UID分组标记 0 admin; 1-499 sysuser; 500+ users
输出样式
%s是字符类型,%d数值类型
printf默认是不输出换行的所以要加\n
10和7是偏移量
默认是右对齐,所有加个- 就是左对齐,就是把不足的位数用空格填充
注意:格式与输出列之间要有逗号
# awk -F: ‘{printf “%-10s %-10d %s\n”,
读前处理和读后处理
# awk -F: ‘BEGIN{i=1} {i++} END {print i}’ /etc/passwd
47
#
# awk -F: ‘BEGIN {print NR,NF}’ /etc/passwd
0 0
#
# awk -F: ‘END {print NR,NF}’ /etc/passwd
46 7
#
试做
找出普通用户的用户名并统计数量
# awk -F: ‘BEGIN{i=0} 3 >= 500 {print1;i++} END {print i}’ /etc/passwd
计算UID相加的总和;计算GID相加的总和
计算VSZ和RSS各自的和 并以M单位显示
循环语句 while(条件) { 动作 条件运算 }# awk -F: '{while($3<3) {print $3,$1;$3++}}' /etc/passwd0 root1 root2 root1 bin2 bin2 daemon# BEGIN块可以独立使用,不需要引入文件# awk 'BEGIN{i=1;while(i<100) {print i;i++}}'
试做
打印100以内的偶数
# awk ‘BEGIN{i=1;while(i<100) {if (i%2==0) print i;i++}}’
x=1do { 动作1 x++ } while (x<5)# awk 'BEGIN{i=5;do{print i;i++}while(i<10)}'# awk 'BEGIN{i=5;do{print i;i++}while(i<1)}'for(预置;条件;递增) { 动作 }# awk 'BEGIN {for (x=1;x<=4;x++) print x }'1234## awk 'BEGIN{for (i=1;i<=4;i++) {for (j=1;j<=4;j++) print i,j}}'
试做
使用嵌套的for循环,打印100-999之间的数,个十百位分别用一个for来打印
# awk ‘BEGIN{OFS=”“;for (i=1;i<=9;i++) {for (j=0;j<=9;j++) {for (n=0;n<=9;n++) print i,j,n}}}’
打印乘法口诀表
# cat 99.sh
#!/bin/bash
awk ‘BEGIN{
for(i=1;i<10;i++)
{
for(j=1;j<=i;j++)
printf “%d*%d=%d “,j,i,j*i
print
}
}'# 打印金字塔# cat jin.sh #!/bin/bashawk 'BEGIN{ num=5 for(i=1;i<=num;i++) { for (n=1;n<=num-i;n++) printf "%s"," " for (j=1;j<=2*i-1;j++) printf "%s","*" print }}'# 逆序输出每个字段达到这样既可/bin/bash/rootroot00xroot# awk -F: '{for (x=NF;x>0;x--) print $x}' /etc/passwd
继续解决上一个试做题的格式问题
# awk -F: ‘/bash/{for (x=NF;x>0;x--) printf "%-13s",x;printf “\n”}’ /etc/passwd
跳转语句break 跳出循环# awk 'BEGIN {for(x=1;x<5;x++) {if (x==3) break;print x }}'12continue 在达到循环底部之前终止当前循环 从新开始下一次循环# awk 'BEGIN {for(x=1;x<5;x++) {if (x==3) continue;print x }}'124next 读入下一行 同时返回脚本顶部 这样可以避免对当前行执行其他操作# awk -F: 'NR > 5 {next} {print $1} END {print NR}' /etc/passwdrootbindaemonadmlp46# exit 使读取动作终止 并将控制移动到END,如果没有END则终止脚本# awk -F: 'NR > 5 {exit} {print $1} END {print NR}' /etc/passwdrootbindaemonadmlp6#
数组
自定义数组
# awk ‘BEGIN {ary[1]=”seker”;ary[2]=”zorro”;print ary[1],ary[2]}’
seker zorro
#
# awk ‘BEGIN {ary[1]=”seker”;ary[2]=”zorro”;for(i in ary) print ary[i]}’
seker
zorro
#
删除一个元素 对元素给空值并不能清除这个元素 要想清除一个元素需要使用delete ary[idx]
# awk ‘BEGIN {ary[1]=”seker”;ary[2]=”zorro”;ary[3]=”blues”;ary[2]=”“;for(i in ary) print ary[i]}’
seker
blues# awk 'BEGIN {ary[1]="seker";ary[2]="zorro";ary[3]="blues";delete ary[2];for(i in ary) print ary[i]}'sekerblues#循环产生数组和取出数组# awk 'BEGIN{n=5;for (i=1;i<=n;i++) ary[i]=i+100;for(m in ary) print m,ary[m]}'4 1045 1051 1012 1023 103# # awk -F: '{ary[NR]=$1} END {for(i in ary) print i,ary[i]}' /etc/passwd1 root2 bin3 daemon4 adm5 lp6 sync7 shutdown8 halt9 mail# awk -F: '{ary[$3]=$1} END {for(i in ary) print i,ary[i]}' /etc/passwd10 uucp11 operator12 games13 gopher14 ftp32 rpc37 rpmARGV 命令行中参数数组 # awk '{for (i in ARGV) {print i,ARGV[i]}}' /etc/passwd /etc/fstab 0 awk 1 /etc/passwd 2 /etc/fstab #### i 为下标; ARGV[i] 下标为i的值
试做
统计每种shell被使用的次数
函数
算术函数 int
[root@stu254 ~]# awk ‘BEGIN {print int(3.9415)}’
3
[root@stu254 ~]#
随机数函数 rand() srand()
rand() 取值 0 > r < 1 之间 默认的种子是系统时间 精确到秒
srand()取值 0 > r < 1 之间 可以指定种子来影响rand()取值数 默认是系统时间 精确到秒
[root@stu254 ~]# awk ‘BEGIN {srand(222);print int(rand()*100000000)}’
90204196
[root@stu254 ~]#
字符串函数
substr(s,x[,y])
返回字符串s中从位置x起至y的子串,如果没有给出y,则从x开始到结束.
[root@stu254 ~]# awk ‘BEGIN {x=”abcdefxyz”;print substr(x,4,3)}’
def
[root@stu254 ~]#
大写小写
sprintf() 本身并不能打印,做格式转换,将数字转换成ASCII字符
awk ‘BEGIN {for(i=97;i<=122;++i) print tolower(toupper(sprintf(“%c”,i)))}’
字符串长度
length() 如果没有给定字符串则使用$0
[root@stu254 ~]# awk ‘BEGIN {print length(“abcdefxyz”)}’
9
gsub(/abc/,”ABC”,x) 全局字符串替换
从x中用匹配的abc正则替换成ABC
[root@stu254 ~]# awk ‘BEGIN {x=”xyzabcxyzabcxyz”;gsub(/abc/,”ABC”,x);print x}’
xyzABCxyzABCxyz
[root@stu254 ~]# sub 第一次的替换
[root@stu254 ~]# awk ‘BEGIN {x=”xyzabcxyzabcxyz”;sub(/abc/,”ABC”,x);print x}’
xyzABCxyzabcxyz
[root@stu254 ~]#
gensub(r, s, h [, t]) Search the target string t for matches of the reg- ular expression r. If h is a string beginning with g or G, then replace all matches of r with s. Otherwise, h is a number indicating which match of r to replace. If t is not supplied, $0 is used instead.
gensub(正则,替换,范围,目标串)
[root@tch254 ~]# awk ‘BEGIN{print gensub(“zorro”,”AAAA”,”2”,”seker zorro zorro seker”)}’
seker zorro AAAA seker
[root@tch254 ~]# echo seker zorro zorro seker | sed ‘s/zorro/AAAA/2’
seker zorro AAAA seker
[root@tch254 ~]#
[root@tch254 ~]# echo seker zorro zorro seker | awk ‘{0=gensub(“zorro”,”AAAA”,”g”);print}’
seker AAAA AAAA seker
[root@tch254 ~]# echo seker zorro zorro seker | awk ‘{0=gensub(“zorro”,”AAAA”,”2”);print}’
seker zorro AAAA seker
[root@tch254 ~]# echo seker zorro zorro seker | awk ‘{0=gensub(“zorro”,”AAAA”,”h”);print}’
seker AAAA zorro seker
[root@tch254 ~]# echo seker zorro zorro seker | awk ‘{0=gensub(“zorro”,”AAAA”,”1”);print}’
seker AAAA zorro seker
[root@tch254 ~]#
系统函数
getline
交互输入
[root@stu254 ~]# awk -F: ‘BEGIN {printf “Enter Number: “;getline ;for(i=1;i<=$0;i++) print i}’
Enter Number: 3
1
2
3
[root@stu254 ~]#
将输入赋值给变量
[root@stu254 ~]# awk -F: ‘BEGIN {printf “Enter Number: “;getline NUM;for(i=1;i<=NUM;i++) print i}’
Enter Number: 3
1
2
3
[root@stu254 ~]#
从文件中读入
[root@tch254 ~]# awk -F: ‘BEGIN {getline < “/etc/passwd” ; print
0 root
[root@tch254 ~]#
awk -F: ‘BEGIN {while (getline < “/etc/passwd” > 0) print 3"\t" 1}’
getline < “/etc/passwd” 从文件中读入,每次读取一行,默认情况下读取的次数等于awk自身引入文件的行数
也可以放到for中来控制读取的次数
0 测试读取的返回值,成功返回1,失败返回-1,0文件末尾
从命令输出中输入
[root@stu254 ~]# awk ‘BEGIN {“uname -a”|getline ;print $3}’
2.6.18-53.el5
[root@stu254 ~]#
system(command)
系统命令要用”“引起来
[root@stu254 ~]# rm -rf abc/
[root@stu254 ~]# awk ‘BEGIN {if(system(“mkdir abc”) != 0 ) print “ERR”}’
[root@stu254 ~]# awk ‘BEGIN {if(system(“mkdir abc”) != 0 ) print “ERR”}’
mkdir: 无法创建目录 “abc”: 文件已存在
ERR
[root@stu254 ~]#
[root@tch254 ~]# awk ‘BEGIN {if(system(“mkdir abc 2>/dev/null”) != 0 ) print “ERR”}’
ERR
[root@tch254 ~]#
awk脚本的介绍 -f 与 #!/bin/awk -f
使用awk添加系统用户
[root@mail ~]# cat useradd.awk
!/bin/awk -f
{
system(“useradd “
}
[root@mail ~]# cat username
myname 1234
[root@mail ~]#
[root@mail ~]# ./useradd.awk ./username
Changing password for user myname.
passwd: all authentication tokens updated successfully.
[root@mail ~]#
- awk讲解步骤
- shell讲解--awk
- Linux awk详细讲解
- 执行awk的步骤
- awk {print $2}的讲解
- linux正则表达式awk讲解
- linux正则表达式awk讲解
- Linux正则表达式awk讲解
- JDBC基本步骤讲解
- ffmpeg 学习步骤讲解
- 实例讲解4--awk命令a
- 实例讲解4--awk命令b
- 实例讲解4--awk命令c
- 实例讲解4--awk命令d
- 实例讲解4--awk命令e
- 实例讲解4--awk命令e续
- 实例讲解4--awk命令f
- 实例讲解4-awk命令g
- 【代码笔记】iOS-json文件的两种解析方式
- 初学者利用git 上传代码到Coding的简单操作步骤
- JUnit 5 简介
- vue 点击弹出当前的text
- 一次oracle数据库大数据表的分区方案设计,以及所踩的坑
- awk讲解步骤
- day05_dtd约束*了解
- DNS 工作机制全面剖析与应用探究
- python描述冒泡排序
- SIM卡文件架构
- Android BOOTCLASSPATH详解
- PAT乙级(Basic Level)练习题 外星人的语言
- MySQL的通用优化方法
- 到底什么是框架?