文本处理工具 awk
命令格式
awk [options] -f awk-script-line filename
options: -F:定义输入字段分隔符,默认的分隔符是空格或者制表符(tab)
command: BEGIN{} {} END{}
行处理前 行处理 行处理后
awk 'BEGIN{print 1+1} {print "demo"} END{print "end....."}' passwd
BEGIN{} 一般用于定义一些变量,例如BEGIN{FS=":",OFS="–"}
awk命令格式
awk 'pattern' filename # awk -F":" '/root/' passwd
awk '{action}' filename # awk -F":" '{print $1}' passwd
awk 'pattern {action}' filename # awk -F":"" '/root/{print $1}' passwd
# awk 'BEGIN{FS=":"} /root/{print $1}' passwd
cmd | awk 'pattern {action}' # df -Ph | grep '/' | awk '$4 > 25000 {print $4}'
awk的工作原理
awk -F":" {print $1,$3} passwd
(1)awk使用一行作为输入,并将这一行赋给内部变量$0,以换行符结束。
(2)每一行被:(默认为空格或者制表符)分解成字段,每个字段存储在已经编号的
变量中,从$1开始,最多达到100个字段。
(3)awk如何知道用空格来分隔字段的呢?因为有一个内部变量来FS
来确定字段分隔符。初始时,FS被赋为空格。
(4)awk打印字段时,将以设置的方式使用print函数进行打印,awk在打印字段前面
加上空格,因为$1,$3之间有一个逗号。它映射为一个内部变量,成为输出字段分隔符OFS,
OFS默认为空格。
(5)awk输出之后,将从文件中获取新的一行,并将其储存在$0中,覆盖原来的
内容,然后将新的字符串分隔成字段进行处理。该过程会持续到所有的处理完毕为止。
记录与字段相关的内部变量
$0: awk变量$0保存当前记录的内容 # awk -F":" '{print $0}' passwd
NR: The total number of input records seen so far # awk -F":" {print NR,$0} passwd hosts (累加数值和)
FNR: the input record number in the current input file # awk -F":" {print FNR $0} passwd hosts (从头开始算)
NF: 保存记录的字段数,$1 $2......$100 # awk -F":" {print $0,NF} passwd
FS: 输入字段分隔符,默认空格 # awk 'BEGIN{FS=":"} {print $1,$2,$3}' passwd
# awk -F":" '/root/{print $1,$3}' passwd
# awk -F"[:\t]" '{print $1,$2,$3}' passwd
OFS: 输出分隔符 # awk -F":" '/root/{print $1,$2,$3,$4}' passwd
# awk -F":" 'BEGIN{FS=":";OFS="+++"} /root/{print $1,$2,$3,$4}' passw
RS: The input record separator,by default a newline. # awk -F":" 'BEGIN{RS=""} {print $0}' passwd
ORS: The output record separator,by default a newline. # awk -F":" 'BEGIN{ORS=""} {print $0}' passwd (将文件每一行合并为1行)
格式化输出
print函数
date | awk '{print "Month:" $2 "\nYear:" $NF}'
awk -F":" '{print "username is:" $1 "\t uid is:" $3}' passwd
awk -F":" '{print "\tusername and uid:" $1,$3}' passwd
printf函数
awk -F":" '{printf "%-15s %-10s %-15s", $1,$2,$3}' passwd
awk -F":" '{printf "|%-15s|%-10s|%-15s|", $1,$2,$3}' passwd
%s 字符类型数据
%d 数值类型数据
%nd n占的位数
- 左对齐,默认为右对齐
printf函数默认不会自动换行,需要手动加\n
使用正则表达式
匹配记录(整行)
awk ‘/^root/’ passwd
awk ‘$0 ~ /^root/’ passwd
awk ‘!/root/’ passwd
awk ‘$0 !~ /^root/’ passwd
匹配字段(匹配操作符 ~ !~)
awk -F":" '$1 ~ /^root/' passwd
比较表达式
比较表达式采用对文本进行比较,只有当条件为真时,才执行指定的动作。
比较表达式使用的关系运算符,用于比较数值和字符串。
awk -F":" '$3 == 0' /etc/passwd
awk -F":" '$3 < 10' /etc/passwd
awk -F":" '$NF == "/bin/bash"' /etc/passwd
awk -F":" '$1 == "root"' /etc/passwd
awk -F":" '$1 ~ /root/' /etc/passwd
awk -F":" '$1 !~ /root/' /etc/passwd
df -Ph | grep '/' | awk '$4 > 250'
条件表达式
awk -F":" '$3>300 {print $0}' /etc/passwd
awk -F":" '{if($3 > 200) print $0}' /etc/passwd
awk -F":" '{ if($3 < 200) {print $0} }' /etc/passwd
awk -F":" '{ if($3 > 200) {print $3} else {print $1}}' /etc/passwd
算术表达式 : + - * / % ^
awk -F":" '$3 *10 > 500' /etc/passwd
awk -F":" '{ if($3 * 10 > 500) {print $0}}' /etc/passwd
awk -F"[:]+" '{ print NF }' /etc/passwd
awk '$7 > 5' data
awk '$2 == "AA" {print $0}' data
awk '$7 != 5' data
awk脚本编程
条件判断
if语句
{ if(express) {do1;do2} }
awk -F":" '{ if($3 == 0) {print $1 " is administrator"} }' /etc/passwd
awk -F":" '{ if($3 > 0 && $3 < 1000) {count++} } END{print count}' /etc/passwd
if…else语句
{ if(express) {do1;do2} else{do3;do4}}
awk -F":" '{ if($3 == 0) {print $1} else {print $7} }' /etc/passwd
awk -F":" '{ if($3 == 0) {count++} else {i++} } END{print "admin:"count; print "user:" i}' /etc/passwd
if…else if…else语句
{ if(express 1) {do1;do2} else if(express 2){do3;do4}} else {do5;do6}
awk -F":" '{ if($3 == 0) {i++} else if($3 > 0 && $3 < 1000) {j++} else {k++}} END{print i; print j; print k}' /etc/passwd
awk使用外部变量
在双引号的情况下使用
var="bash"
echo "linux script" | awk "gsub(/linux/,\"$var\")"
在单引号的情况下使用
var="bash"
echo "linux script" | awk 'gsub(/linux/, "'" $var "'")'
awk -v user=root -F":" '$1 == user' /etc/passwd
awk -v user=root -F:":" '$1 == "user" {print $0}' /etc/passwd
df -h | awk '{if(int($5) > 80) {print $6":" $5}}'
i=80
df -h | awk '{if(int($5) > "$i") {print $6":" $5}}'
echo "linux script" | awk -v var="bash" 'gsub(/linux/,var)'