linuxawkfor循环,Linux之awk详解
'#Gun awk的相关⽤法
awk的⼯作原理
⼀次读取⼀⾏⽂本,按输⼊分隔符进⾏切⽚,切成多个组成部分,将每⽚直接保存在内建的变量中,$1,$2,$3....,引⽤指定的变量,可以显⽰指定断,或者多个断。如果需要显⽰全部的,需要使⽤$0来引⽤。可以对单个⽚断进⾏判断,也可以对所有断进⾏循环判断。其默认分隔符为空格
awk的基本⽤法格式
awk [options] 'program'
语句之间⽤分号分隔
[options]
-F : 指明输⼊时⽤到的字段分隔符
-v var=VALUE : ⾃定义变量
在awk中变量的引⽤不需要加$,⽽是直接引⽤
awk⽤法的简要介绍
第⼀种模式
awk [options] 'scripts'
在这种模式中,scripts主要是命令的堆砌,对输⼊的⽂本⾏进⾏处理,通过命令print,printf或是输出重定向的⽅式显⽰出来,这⾥经常⽤到的知识点是:awk的内置变量,以及命令print和printf的使⽤
第⼆种模式
awk [options] 'PATTERN{action}'
在这种模式中,最重要的是5种模式和5种action的使⽤,以及awk的数组的使⽤和内置函数
第⼀种模式
1、print
1、各项⽬之间使⽤逗号隔开,⽽输出时则以空⽩字符分隔
2、输出的Item可以为字符串或数值,当前记录的字段(如$1)、变量或awk的表达式,数值会先转换为字符串,⽽后再输出
3、print命令后⾯的Item可以省略,此时其功能相当于print $0,因此,如果想输出空⽩⾏,则需要使⽤print""
4、如果引⽤变量$1或其他的,是不能使⽤引号引起来
2、内置变量
FS : input field seperator,输⼊的分隔符,默认为空⽩字符
OFS: output field seperator,输出的分隔符,默认为空⽩字符
RS : input record seperator,输⼊的换⾏符
ORS: output record seperator,输出时的换⾏符
NF : number of field ,字段个数
awk '{print NF}' /etc/fstab :打印每⾏的最后⼀个字段为第⼏个字段,这⾥是数量引⽤,不是对应的值
引⽤
awk '{print $NF}' /etc/fstab : 打印每⾏中的最后⼀个字段
NR : number of record,⽂件中的⾏数
awk '{print NR}' /etc/fstab: 打印⾏号,其会个⾏号都显⽰
awk 'END{print NR}' /etc/fstab: 显⽰⽂本的总⾏数,其只是在⽂本处理完成后,只显⽰⼀次⾏号awk '{print NR}' file1 file2 : 会每把所有⽂档进⾏总的编号,⽽不是单独对⽂件进⾏编号
FNR : 对每个⽂件进⾏⾏数单独编号
awk '{print FNR}' file1 file2 : 会对每个⽂件的⾏数进⾏单独的编号显⽰
FILENAME : awk命令所处理的⽂件的名称
awk '{print FILENAME}' file1 : 显⽰当前⽂件名,但会每⾏显⽰⼀次
awk 'END{print FILENAME}' file1 : 显⽰当前⽂件名,但只会显⽰⼀次
ARGC : 命令⾏中参数的个数,其awk命令也算⼀个参数
awk 'END{print ARGC}' /etc/fstab : 显⽰共有⼏个参数
linux重定向ARGV : 其是⼀个数组,保存的是命令⾏所给定的各参数
awk 'END{print ARGV[0]}' /etc/fstab : 显⽰第⼀个参数,默认第⼀个参数个awk命令本⾝
3、⾃定义变量
-v var=VALUE : 在选项位置定义
awk 'BEGIN{test="hello";print test}' : 在program中定义
变量在program中定义时,需要使⽤引号引起来
4、printf命令
其格式化输出:printf FORMAT,
要点:
1、其与print命令最⼤不同是,printf需要指定format
2、printf后⾯的字串定义内容需要使⽤双引号引起来
3、字串定义后的内容需要使⽤","分隔,后⾯直接跟
4、format⽤于指定后⾯的每个item的输出格式
5、printf语句不会⾃动打印换⾏符,\n
格式符
%c: 显⽰字符的ASCII码
%d,%i : 显⽰⼗进制整数
%e,%E: 科学计数法数值显⽰
%f : 显⽰为浮点数
%g,%G: 以科学数法或浮点形式显⽰数值
%s: 显⽰字符串
%u: ⽆符号整数
%%: 显⽰%号⾃⾝,相当于转义
修饰符
N : 显⽰宽度
- : 左对齐(默认为右对齐)
+ : 显⽰数值符号
⽰例:
awk -F: '{printf "%s\n",$1}' /etc/fstab
awk -F: '{printf "username: %s,UID:%d\n",$1,$3}' /etc/passwd
awk -F: '{printf "username: %-20s shell: %s\n",$1,$NF}' /etc/passwd
输出重定向
print items > "output-file"
print items >> "output-file"
print items | command
特殊⽂件描述符:
/dev/stdin :标准输⼊
/dev/stdout:标准输出
/dev/stderr:错误输出
/dev/fd/N : 某特定⽂件描述符,如/dev/stdin就相当于/dev/fd/0
⽰例
awk -F: '{printf "%-15s %i\n",$1,$3 > "/dev/stderr"}' /etc/passwd
第⼆种模式
awk [option] 'PATTERN{action}'
PATTERN的使⽤
REGEXP:正则表达式,格式为/regular expression/,仅处理能够被此处模式匹配到的⾏
awk '/^UUID/{print $1}' /etc/fstab
awk '!/^UUID/{print $1}' /etc/fstab
relational expression:表达式,其值⾮0或为⾮空字符时满⾜条件,⽤运算符~(匹配)和!~(不匹配)
$1 ~ /foo/ 或者 $1 == "magedu"
Ranges : 指定匹配范围,格式为/pat1/,/pat2/
awk -F: '{NR>=2&&<=10){print $1}' /etc/passwd
awk -F: /^root/,/^myuser/{print $1}' /etc/passwd
注意:不⽀持直接给出数字的格式
BEGIN/END模式 : 特殊模式,仅在awk命令执⾏前运⾏⼀次或结束前运⾏⼀次
awk -F: 'BEGIN{print "Username ID Shell"}{printf "%-10s%-10s%-20s\n",$1,$3,$7}' /etc/passwd :先打印⼀个表头
awk -F: 'BEGIN{print "username ID Shell"}{printf "%-10s%-10s%-20s\n",$1,$3,$7}END{print "end of report."} /etc/passwd :打印⼀个表尾
Empty(空模式):匹配任意输⼊⾏
/正则表达式/:使⽤通配符的扩展集。
关系表达式:可以⽤下⾯运算符表中的关系运算符进⾏操作,可以是字符串或数字的⽐较,如$2>$1选择第⼆个字段⽐第⼀个字段长的⾏。
模式匹配表达式:
模式,模式:指定⼀个⾏的范围。该语法不能包括BEGIN和END模式。
BEGIN:让⽤户指定在第⼀条输⼊记录被处理之前所发⽣的动作,通常可在这⾥设置全局变量。
END:让⽤户在最后⼀条输⼊记录被读取之后发⽣的动作。
常见的Action
1)Expressions
Control statements :if while等
Compound statements:组合语句
Input statements
Output statements
控制语句
1、if-else
语法:if (condition){then-body} else{[else-body]}
⽰例:
awk -F: '{if($3>=1000)print $1,$3}' /etc/passwd
awk -F: '{if($3>=1000){printf "Common user: %s\n",$1} else {printf "root or sysuser: %s\n",$1}}' /etc/passwd
awk -F: '{if($NF=="/bin/bash")print $1}' /etc/passwd
awk -F: '{if(NF>5) print $0}' /etc/fstab
df -h | awk -F[%] '/^/dev/{print $1}' | awk {if($NF>=20) print $1}'
awk -F: '{if($1=="root") print $1,"Admin";else print $1, "Common User"}' /etc/passwd
awk -F: '{if($1=="root") printf "%-15s: %s\n",$1,"Admin";else printf "%-15s: %s\n",$1, "Common user"}' /etc/passwd
awk -F: -v sum=0 '{if($3>=500) sum++}END{print sum}' /etc/passwd : 统计⽤户ID⼤于500的有多少⾏
awk -F: -v OFS="\t" '{if($3<=999)printf "Sys user:\t%-15s ID is :%d\n", $1,$3;else{printf "Common user:\t%-15s ID is
:
%d\n",$1,$3}}' /etc/passwd :可以使⽤\t制表符控制 输出格式
2、while:⽤于循环字段的
语法:while (condition){statement1;statment2;....}
⽰例:
awk '/^[[:space:]]*linux16/{print}' /boot/grub2/grub.cfg
awk '/^[[:space:]]*linux16/{i=1;while(i<=NF){print $i,length($i);i++}}' /etc/grub2.cfg :对每个字段进⾏字符个数统计
awk '/^[[:space:]]]*linux16/{i=1;while(i<=NF){if(length($i)<=7)print $i,length($i);i++}}' /etc/grub2.cfg
awk -F: '{i=1;while(i<=3){print $i;i++}}' /etc/passwd:打印⽤户名、密码占位符、ID
awk -F: '{i=1;while(i<=NF){if(length($i)>=4){print $i};i++}}' /etc/passwd : 字段⼤⼩于等于4的都显⽰
3、do-while
语法:do {statement1,statement2,....} while (dondition)
⽰例:
awk -F: '{i=1;do{print $i;i++}while(i<=3)}' /etc/passwd :打印⽤户名、密码占位符、UID
4、for
语法:for(variable assignment;condition;iteration process){ statement1,statement2,...}
⽰例:
awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg
awk -F: '{for(i=1;i<=3;i++)print $i}' /etc/passwd
awk -F: '{for(i=1;i<=NF;i++) { if (length($i)>=4) {print $i}}}' /etc/passwd
5、for循环还可以⽤来遍历数组元素
语法:for (i in array) {statement1,statement2,....}
⽰例
awk -F: '$NF!~/^$/{BASH[$NF]++}END{for(A in BASH){printf "%15s:%i\n",A,BASH[A]}}' /etc/passwd
awk ‘{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}’ /etc/fstab
awk '/^UUID/{filesystem[$3]++}END{for (i in filesystem) {print i,filesystem[i]}}' /etc/fstab :统计/etc/fstab中各⽂件系统的次数netstat -tan | awk '/^tcp>/{state[$NF]++}END{for(i in state) {print i,state[i]}}' : 统计各连接状态的次数
awk '{ip[$1]++} END {for (i in ip) {print i,ip[i]}}' /var/log/httpd/access_log : 统计访问⽇志中各IP的访问次数
6、case
语法:switch (expression) { case VALUE or /REGEXP/: statement1, statement2,... default: statement1, ...}
7、break和continue
break [n]
continue : 进⼊下⼀个字段
8、next
功能:提前结束本⾏⽂本的处理,并接着处理下⼀⾏
⽰例:
awk -F: '{if($3%2==0) next;print $1,$3}' /etc/passwd
awk -F: ‘{if ($3%2!=0) next;print $1,$3}’ /etc/passwd
awk的操作符
1、算术操作符
-x : 负值
+x : 转换为数值

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。