Linux文本文件处理(3)

本文主要介绍awk命令的用法。

1. awk简介

awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk。
awk名字来源于三位创造者Aho、Weinberger和Kernighan统称。
awk擅长处理文本数据。

2. 基本用法

awk [-Ffs] [-v var=value] [program | -f progfile …] [file …]
选项与参数:
-F 指定域分隔符,例如:-F “|”,即以|作为域分隔符,默认分隔符为一个或多个空格或TAB,即”[[:space:]][[:space:]]*”。
-v 定义变量,从shell给awk传递变量,如-vDATE=$DATE,即将shell中$DATE变量值传递给awk变量DATE。
-f 指定脚本文件,例如-f progfile。
program 操作模块

示例:

1
2
3
4
5
6
# awk -F ":" '{print $1,$2}' /etc/passwd			    	-F 分隔符 $1是第一列 $2是第二列
# awk '{print $0}' /etc/passwd 打印所有列
# awk -F: '{print $1}' /etc/passwd 打印第一列
# awk -F: '{print $1"\thaha\t"$3}' /etc/passwd 打印第一,三列
# awk -F":" '{print $1" 的uid是 "$3}' /etc/passwd
# echo "haha,hehe.heihei" |awk -F"[,.]" '{print $1}' 分隔符可以有多个
  • 模式匹配
    格式:awk ‘/patten/ {action} ‘ filename
    //纯字符匹配
    !//纯字符不匹配
    ~//字段值匹配
    !~//字段值不匹配
    ~/a1|a2/字段值匹配a1或a2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# awk '/mysql/' /etc/passwd
# awk '/mysql/{print }' /etc/passwd
# awk '/mysql/{print $0}' /etc/passwd --三条指令结果一样
# awk '!/mysql/{print $0}' /etc/passwd --输出不匹配mysql的行
# awk '/mysql|mail/{print}' /etc/passwd
# awk '/mysql|postfix|root/' /etc/passwd
# awk '!/mysql|mail/{print}' /etc/passwd
# awk '/mail/,/mysql/{print}' /etc/passwd --区间匹配
# awk '/^root/,/^mail/' /etc/passwd --区间匹配
# awk '/[2][7][7]*/{print $0}' /etc/passwd --匹配包含27为数字开头的行,如27,277,2777...
# awk -F: '$1~/mail/{print $1}' /etc/passwd --$1匹配指定内容才显示
# awk -F: '$3~/^0$/{print $1}' /etc/passwd
# awk -F: '{if($1~/mail/) print $1}' /etc/passwd --与上面相同
# awk -F: '$1!~/mail/{print $1}' /etc/passwd --不匹配
# awk -F: '$1!~/mail|mysql/{print $1}' /etc/passwd
  • 操作模块

awk [-Ffs] ‘BEGIN {处理文件前执行的代码块} {处理文件过程中执行的代码块} END {处理文件后执行的代码块}’ filename

BEGIN{


END{

BEGIN和END只执行一次。

1
2
3
4
5
6
7
8
9
10
11
12
13
# awk -F: '{print "用户名\t\tUID"}{print $1"\t"$3}' /etc/passwd
# awk -F: 'BEGIN{print "用户名\t\tUID"}{print $1"\t"$3}' /etc/passwd

# head -1 /etc/passwd |awk -F: '{print $7":"$6":"$5":"$4":"$3":"$2":"$1}'
# head -1 /etc/passwd |awk -F: 'BEGIN {OFS=":"}{print $7,$6,$5,$4,$3,$2,$1}'
# head -1 /etc/passwd | awk 'BEGIN{FS=":"}{OFS="@"; print $7,$6,$5,$4,$3,$2,$1}'
# head -1 /etc/passwd | awk 'BEGIN{FS=":";OFS="#"}{print $7,$6,$5,$4,$3,$2,$1}'

awk可以用做小数(浮点数)的运算
# echo $[1.23*2] --错误做法
# echo |awk '{print 1.23*2}' --正确做法
# echo 1.23*2 | bc --正确做法
# awk 'BEGIN{print 1.23*2}'
  • 内置变量
属性 说明
$0 当前记录行,代表一行记录
$1到n 当前记录的第n个字段,字段间由FS分隔
FS 输入字段分隔符,默认是空格或tab
NF 当前记录中的字段个数,就是有多少列,一般取最后一列字段
NR 已经读出的记录数,就是行号,从1开始
RS 输入的记录分隔符,默认为换行符
OFS 输出字段分隔符,默是空格
ORS 输出的记录分隔符,默认为换行符

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
打印第五行
# head -5 /etc/passwd |tail -1
# awk 'NR==5 {print $0}' /etc/passwd
# awk '{if (NR==5) print $0}' /etc/passwd

打印第五行和第六行
# awk 'NR==5 || NR==6 {print $0}' /etc/passwd
# awk 'NR>=5 && NR<=6 {print $0}' /etc/passwd

打印五到十行,并在前面加上行号
# awk 'NR<=10 && NR>=5 {print FNR,$0}' /etc/passwd

打印奇数行 (删除偶数行)
# awk 'NR%2==1 {print FNR,$0}' /etc/passwd

打印偶数行 (删除奇数行)
# awk 'NR%2==0 {print FNR,$0}' /etc/passwd
---------------- The End ----------------