0
点赞
收藏
分享

微信扫一扫

awk-内置变量、操作符

1.内置变量

FS 输入字段分隔符,默认是空格或制表符

OFS 输出字段分隔符,默认是空格

RS 输入记录分隔符,默认是换行符\n

ORS 输出记录分隔符,默认是护身符\n

NF 统计当前记录中字段个数

NR 统计记录编号,每处理一行,编号就会+1

FNR 同上,与NR不同的是处理第二个文件时,编号会重新计数

ARGC 命令行参数数量

ARGV 命令行参数数组序列数组,下标从0开始,ARGV[0]是awk

ARGIND 当前正在处理的文件索引值。第一个文件是1,第二个是2,以此类推

ENVIRON 当前系统的环境变量

FILENAME输出当前处理的文件名

IGNORECASE忽略大小写

SUBSEP 数组中下标的分隔符,默认为"\034"


在程序开始前重新赋值FS变量,改变默认分隔符为冒号,与-F一样

[root@study ~]# awk 'BEGIN{FS=":"}{print $1,"\t",$2}' /etc/passwd |head -5
root x
bin x
daemon x
adm x
lp x

也可以用-v重置这个变量

[root@study ~]# awk -vFS=':' '{print $1,"\t",$2}' /etc/passwd |head -5
root x
bin x
daemon x
adm x
lp x

也可以字符串拼接实现分隔

[root@study ~]# awk -vFS=':' '{print $1"#"$2}' /etc/passwd |head -5
root#x
bin#x
daemon#x
adm#x
lp#x

以指定字符作为行分隔符来处理记录

[root@study ~]# echo "www.baidu.com/user/test.html" | awk 'BEGIN{RS="/"}{print $0}'
www.baidu.com
user
test.html

RS也支持正则

[root@study ~]# seq -f "str%02g" 10|sed 'n;n;a----'|awk 'BEGIN{RS="-+"}{print $1}'
str01
str04
str07
str10

替换某个字符

[root@study ~]# tail -2 /etc/services |awk 'BEGIN{RS="/";ORS="#"}{print $0}'
iqobject 48619#udp # iqobject
matahari 49000#tcp # Matahari Broker

NF是字段个数

[root@study ~]# echo a b c d e f|awk '{print NF}'
6
[root@study ~]# echo a b c d e f|awk '{print $NF}'
f
[root@study ~]# echo a b c d e f|awk '{print $(NF-1)}'
e
#排除倒数第一、二列
[root@study ~]# echo a b c d e f|awk '{$NF="";$(NF-1)="";print $0}'
a b c d
#排除第一列
[root@study ~]# echo a b c d e f|awk '{$1="";print $0}'
b c d e f

打印行数

[root@study ~]# tail -5 /etc/services |awk '{print NR,$0}'
1 com-bardac-dw 48556/tcp # com-bardac-dw
2 com-bardac-dw 48556/udp # com-bardac-dw
3 iqobject 48619/tcp # iqobject
4 iqobject 48619/udp # iqobject
5 matahari 49000/tcp # Matahari Broker
#打印总行数
[root@study ~]# tail -5 /etc/services |awk 'END{print NR}'
5
#打印第三行
[root@study ~]# tail -5 /etc/services |awk 'NR==3'
iqobject 48619/tcp # iqobject
#打印第三行第2列
[root@study ~]# tail -5 /etc/services |awk 'NR==3{print $2}'
48619/tcp
#打印前三行
[root@study ~]# tail -5 /etc/services |awk 'NR<=3{print NR,$0}'
1 com-bardac-dw 48556/tcp # com-bardac-dw
2 com-bardac-dw 48556/udp # com-bardac-dw
3 iqobject 48619/tcp # iqobject

awk-内置变量、操作符_数组

ARGC是命令行参数数量

ARGV是将命令行参数存到数组,元素由ARGC指定,数组下标从0开始

[root@study ~]# awk 'BEGIN{print ARGC}' 1 2 3
4
[root@study ~]# awk 'BEGIN{print ARGV[0]}' 1 2 3
awk
[root@study ~]# awk 'BEGIN{print ARGV[1]}' 1 2 3
1

ARGIND是当前正在处理的文件索引值,第一个文件是1,第二个文件是2,以此类推,从而可以通过这种方式判断正在处理哪个文件。

[root@study ~]# cat a b
a
b
c
c
d
e
[root@study ~]# awk '{print ARGIND,$0}'
a
0 a
^[[A^C
[root@study ~]# awk '{print ARGIND,$0}' a b
1 a
1 b
1 c
2 c
2 d
2 e
[root@study ~]# awk 'ARGIND==1{print "a->"$0};ARGIND==2{print "b->"$0}' a b
a->a
a->b
a->c
b->c
b->d
b->e

2.

ENVIRON调用系统变量,如果是设置的环境变量,还需要用export导入到系统变量才可以调用

[root@study ~]# awk 'BEGIN{print ENVIRON["HOME"],ENVIRON["USER"]}'
/root root
[root@study ~]# echo $a
123
[root@study ~]# awk 'BEGIN{print ENVIRON["a"]}'

[root@study ~]# export a
[root@study ~]# awk 'BEGIN{print ENVIRON["a"]}'
123

10.

FILENAME是当前处理文件的文件名

[root@study ~]# awk 'FNR==NR{print FILENAME".txt\t"$0}FNR!=NR{print FILENAME".txt\t"$0}' a b
a.txt a
a.txt b
a.txt c
b.txt c
b.txt d
b.txt e

忽略大小写,等于1表示忽略大小写

[root@study ~]# echo a A b BA |xargs -n1|awk 'BEGIN{IGNORECASE=1}/A/'
a
A
BA

2.

操作符

(....)  分组

$  字段引用

++ --  递增和递减

+- !  加号,减号,逻辑否定

* / %  

+ -

|  |&  管道,用于getline,print和printf

< > <= >= != ==

~  !~  正则表达式匹配,否定正则表达式匹配

in  数组成员

&&   ||

?:

= += -= *= /= %= ^=变量赋值运算符

在awk中,有3种情况表达式为假:数字是0,空字符串和未定义的值。

数值运算,未定义变量初始值为0。字符运算,未定义变量初始值为空。

截取整数

[root@study ~]# echo "123abc abc456 234abd546"|xargs -n1|awk '{print +$0}'
123
0
234
[root@study ~]# echo "123abc abc456 234abd546"|xargs -n1|awk '{print -$0}'
-123
0
-234

打印奇数行、偶数行

[root@study ~]# seq 6|awk 'i=!i'
1
3
5
[root@study ~]# seq 6|awk '!(i=!i)'
2
4
6

awk-内置变量、操作符_数组_02

管道符的使用

[root@study ~]# echo 1 3 2 5 6 4|xargs -n1|awk '{print $0|"sort"}'
1
2
3
4
5
6

正则表达式匹配

[root@study ~]# seq 5|awk '$0~3{print $0}'
3
[root@study ~]# seq 5|awk '$0!~3{print $0}'
1
2
4
5
[root@study ~]# seq 5|awk '$0!~/[34]/{print $0}'
1
2
5
[root@study ~]# seq 5|awk '$0~/[34]/{print $0}'
3
4
[root@study ~]# seq 5|awk '$0~/[^34]/{print $0}'
1
2
5

判断数组成员

[root@study ~]# awk 'BEGIN{a["a"]=123}END{if("a" in a)print "yes"}' < /dev/null
yes

三目运算作为一个表达式,里面不允许写print

[root@study ~]# awk 'BEGIN{print 1==1?"yes":"no"}'
yes

替换换行符为逗号

[root@study ~]# seq 5|awk '{print n=n?n","$0:$0}'
1
1,2
1,2,3
1,2,3,4
1,2,3,4,5
[root@study ~]# seq 5|awk '{n=n?n","$0:$0}END{print n}'
1,2,3,4,5

每三行后添加新行

[root@study ~]# seq 10|awk '{print NR%3?$0:$0"\n"}'
1
2
3

4
5
6

7
8
9

10

两行合并到一行

[root@study ~]# seq 6|awk '{printf NR%2!=0?$0" ":$0"\n"}'
1 2
3 4
5 6
[root@study ~]# seq 6|awk '{printf NR%2!=0?$0" ":$0"\n"}'
1 2
3 4
5 6
[root@study ~]# seq 6|awk 'ORS=NR%2?" ":"\n"'
1 2
3 4
5 6
[root@study ~]# seq 6|awk '{if(NR%2)ORS=" ";else ORS="\n";print}'
1 2
3 4
5 6

变量赋值

字段求和
[root@study ~]# seq 5|awk '{sum+=1}END{print sum}'
5
[root@study ~]# seq 5|awk '{sum+=$0}END{print sum}'
15


举报

相关推荐

0 条评论