awk 变量

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了awk 变量相关的知识,希望对你有一定的参考价值。

awk 变量

1,-F 指明输入时用到的字段分隔符

awk -F: ‘{print $1}‘/etc/passwd

使用冒号作为分隔符,打印passwd的第一行

2,使用print打印字符串

awk -F: ‘{print "hello,awk"}‘ /etc/passwd

注意:
passwd文件有多少行,就打印多少行hello,awk
hello,awk 的双引号不能去掉,用作表示hello,awk是字符串
大括号外面使用单引号

awk -F: ‘{print "hello,awk"}‘
nihao  
hello,awk  
zaijian  
hello,awk

注意:
命令行后面不加文件参数,那么awk等待用户输入,每输入一行,打印一次hello,awk awk,可以读取标准输入,处理字符串

例如:

awk -F: ‘{print "hello,awk"}‘ < /etc/fstab
hello,awk  
hello,awk  
hello,awk  
hello,awk

使用标准输入和管道也可以得到相同效果

3,默认参数

awk可以不指定分隔符,默认使用空白符,并且没有指定个数

df |awk ‘{print $6}‘
Mounted  
/  
/dev/shm  
/boot

省略action 默认执行print $0(打印所有)

awk ‘{print}‘ /etc/issue
CentOS release 6.9 (Final)  
Kernel \r on an \m

4,BEGIN 和 END 用法:

awk -F: ‘BEGIN{print "username userid"}{print $1,$3}END{print "finish"}‘ /etc/passwd

注意:
BEGIN{print "username userid"} BEGIN 语句,在print之前执行 BEGIN 使用大写
END{print "finish"}END 语句在print之后执行 END 使用大写

username userid  
root 0  
bin 1  
daemon 2  
user7 508  
user8 509  
finish

5,使用BEGIN 进行计算

awk ‘BEGIN{print 2*10}‘
20

注意:
BEGIN 不可以省略,不可以使用END替换

awk ‘BEGIN{print"2+4"}‘
2+4

注意:
{print "2+4"}使用双引号则会打印2+4,而不是计算结果

6,自定义变量(FS输入字段分隔符)

awk -v FS=":" ‘{print $1,$3}‘ /etc/passwd
root 0  
bin 1  
daemon 2  
adm 3  
lp 4  
sync 5

注意:
使用自定义变量的时候,需要添加-v选项,格式为:FS="变量"

7,自定义变量(F和自定义变量FS的区别)

A=":"; awk -F"$A" ‘{print $1,$3}‘ /etc/passwd
root 0  
bin 1  
daemon 2

注意:
定义一个变量,A=":"
在awk 参数-F 中可以调用这个bash变量

A=":"; awk -v FS="$A" ‘{print $1,$3}‘ /etc/passwd
root 0  
bin 1  
daemon 2

注意:
使用-v FS="$A"调用bash中的变量可以和 -F"$A"达到同样的效果

-v FS=“变量” 和 -F“变量” 的区别在于:
在{print}中可以调用FS变量,而使用-F,则在{print}中无法调用bash变量

A=":"; awk -v FS="$A" ‘{print $1,FS,$3}‘ /etc/passwd
root : 0  
bin : 1  
daemon : 2  
adm : 3
A=":"; awk -F"$A" ‘{print $1,$A,$3}‘ /etc/passwd
root root:x:0:0:root:/root:/bin/bash 0  
bin bin:x:1:1:bin:/bin:/sbin/nologin 1  
daemon daemon:x:2:2:daemon:/sbin:/sbin/nologin 2

注意: FS放在$1和$2之间,在输出是会调用变量FS的值,打印到屏幕
而将$A放在$1和$2之间,则无法打印$A的变量

A=":"; awk -F"$A" ‘{print $1,":",$3}‘ /etc/passwd (冒号两边有逗号)
root : 0  (冒号两边有空格)
bin : 1  
daemon : 2  
adm : 3
A=":"; awk -F"$A" ‘{print $1":"$3}‘ /etc/passwd (冒号两边没有逗号)
root:0  (冒号两边没有空格)
bin:1  
daemon:2

8,自定义变量OFS,输出字段分隔符

输出字段分隔符,默认为空白字符

A=":";awk -v FS="$A" -v OFS="+++" ‘{print $1,$3}‘ /etc/passwd
root+++0  
bin+++1  
daemon+++2

注意:
使用OFS自定义$1和$2中间的字符(默认是空白)
使用OFS时候,前边需要再加一次-v
也可以使用在$1和$2之间插入“+”起到同样效果(“+”两侧没有逗号)

A=":";awk -v FS="$A" ‘{print $1"+++"$3}‘ /etc/passwd
root+++0  
bin+++1  
daemon+++2

9,自定义RS,指定输入时的换行符,原换行符仍有效,不会消失

awk ‘{print $0}‘ f1 (查看f1 示例文件)
a b c  
aa bb cc  
aaa bbb ccc  
aaaa bbbb  
aaaaa
awk -v RS=" " ‘{print $0}‘ f1 (以空格为换行符,显示所有,原换行符仍然有效)
a  
b  
c  (c与aa之间有换行符,现在仍然有效,所以显示出两行)
aa  
bb  
cc  
aaa  
bbb  
ccc  
aaaa  
bbbb  
aaaaa
awk -v RS=" " ‘{print $1,$2,$3}‘ f1  
(以空格为分换行符,打印f1下的第一列,二列,三列,没有第三列,所以不打印)
a  
b  
c aa (c与aa之间存在回车符号,aa是第二列)
bb  
cc aaa 
bbb  
ccc aaaa 
bbbb aaaaa

注意:
对于awk来说以空格为换行符,文件内排列如下:
a空格b空格c回车aa空格bb空格cc回车aaa空格bbb空格ccc回车aaaa空格bbbb回车aaaaa
使用awk进行拆分打印

a空格|
b空格|
c回车aa空格|
bb空格|
cc回车aaa空格|
bbb空格|
ccc回车aaaa空格|
bbbb回车aaaaa空格|

10,自定义ORS,指定输出时的换行符,代替原来的换行符

注意:
“ ” -- 空,代表空格,回车,tab 表格

awk -v RS=" " -v ORS="===" ‘{print $1,$2}‘ f1  
(以空为换行符,然后再用===代替换行符)
a ===b ===c aa===bb ===cc aaa===bbb ===ccc aaaa===bbbb aaaaa=== ===
awk -v RS=" " -v OFS="===" ‘{print $1,$2}‘ f1  
(以空为换行符,然后再用===代替分隔符)
a===  
b===  
c===aa (c 和 aa之间有换行符,也属于空白符,被===代替,只要是空白符,都默认作为字段分隔符) 
bb===  
cc===aaa  
bbb===  
ccc===aaaa  
bbbb===aaaaa  
===

11,NR显示行号,用在{print}之内 ,FNR分别显示行号

awk ‘{print NR,$0}‘ f1
1 a b c  
2 aa bb cc  
3 aaa bbb ccc  
4 aaaa bbbb  
5 aaaaa
awk ‘{print NR,$0}‘ f1 f2 (两个文件连续显示)
1 a b c  
2 aa bb cc  
3 aaa bbb ccc  
4 aaaa bbbb  
5 aaaaa   
6 1 2 3  
7 11 22 33   
8 111 222 333
awk ‘{print FNR,$0}‘ f1 f2 (两个文件分别显示行号)
1 a b c  
2 aa bb cc  
3 aaa bbb ccc  
4 aaaa bbbb  
5 aaaaa   
1 1 2 3  
2 11 22 33   
3 111 222 333

12,NF显示字段数

awk ‘{print NF,$0}‘ f1
3 a b c  
3 aa bb cc  
3 aaa bbb ccc  
2 aaaa bbbb  
1 aaaaa

注意:
打印最后一列可以使用变量$NF

awk ‘{print NF,$NF}‘ f1
3 c  
3 cc  
3 ccc  
2 bbbb  
1 aaaaa

注意:
打印倒数第二行可以使用$(NF-1)

awk ‘{print NF,$(NF-1)}‘ f1
3 b
3 bb
3 bbb
2 aaaa
1 aaaaa

注意:
可以在{print} 内添加文件名变量,打印文件名

awk ‘{print NF,FILENAME,$0}‘ f1
3 f1 a b c
3 f1 aa bb cc
3 f1 aaa bbb ccc
2 f1 aaaa bbbb
1 f1 aaaaa

13,ARGC 命令行参数个数

awk ‘{print NF,FILENAME,$0,ARGC}‘ f1
3 f1 a b c 2 (命令行参数个数2)
3 f1 aa bb cc 2
3 f1 aaa bbb ccc 2
2 f1 aaaa bbbb 2
1 f1 aaaaa  2

14,ARGV 命令行数组

awk ‘BEGIN{print ARGC,ARGV[0],ARGV[1]}‘ f1
2 awk f1 (2个命令行,ARGC[0]是awk,ARGV[1]是f1)

15,自定义变量应用

使用-v 定义变量:

awk -v title="hello" ‘{print title,$0}‘ f1
hello a b c
hello aa bb cc
hello aaa bbb ccc
hello aaaa bbbb
hello aaaaa

在{ }内定义变量

awk ‘{title="hello";print title,$0}‘ f1
hello a b c
hello aa bb cc
hello aaa bbb ccc
hello aaaa bbbb
hello aaaaa

{ }之内定义的优先级高于 -v定义优先级

awk -v title="nihao" ‘{title="hello";print title,$0}‘ f1
hello a b c
hello aa bb cc
hello aaa bbb ccc
hello aaaa bbbb
hello aaaaa

-v 可以调用shell 内变量,而{ } 不可以

A="hello";awk -v title=$A ‘{print title,$0}‘ f1
hello a b c
hello aa bb cc
hello aaa bbb ccc
hello aaaa bbbb
hello aaaaa
A="hello";awk ‘{print $A,$0}‘ f1 (以下为错误输出,但是很显然没有输出$A的值)
a b c a b c
aa bb cc aa bb cc
aaa bbb ccc aaa bbb ccc
aaaa bbbb aaaa bbbb
aaaaa  aaaaa

以上是关于awk 变量的主要内容,如果未能解决你的问题,请参考以下文章

利用awk赋值

使用 ksh(AIX) 时如何在 awk 中调用变量? [复制]

如何创建片段以重复变量编号中的代码行

awk不分配变量并使用$ 0代替

如何使用Android片段管理器传递变量[重复]

AWK ( 二 )