Linux Shell学习--awk命令详解
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux Shell学习--awk命令详解相关的知识,希望对你有一定的参考价值。
(1)、awk介绍
awk是由Alfred Aho 、Peter Weinberger 和 Brian Kernighan于1977年开发的变成语言,awk是上述三位创建者姓的首字母。
Awk的基本语法与c语言类似,如果对c语言很熟悉,那么学习awk编程也将事半功倍。
Awk功能与sed相似,都是用来进行文本处理的,awk语言可以从文件或字符串中基于指定规则浏览和抽取信息,在抽取信息的基础上,才能进行其他文本操作。
awk是一款设计用于数据流的工具。它颇有玩头的原因就在于可以对列和行进行操作。awk有很多内建的功能,比如数组、函数等,这是它和C语言的相同之处。灵活性是awk最大的优势。
(2)、awk工作原理
awk程序由一个主输入循环维持,主输入循环反复执行,直到终止条件被触发。
主输入循环无须人工书写,awk已经搭好主输入循环的框架。
主输入循环自动依次读取输入文件行,以供处理,处理文件的动作根绝不同功能需求来进行添加。
Awk编程模型三个阶段:
读输入文件之前的执行代码段-由BEGIN关键字标识
读取输入文件时的执行代码
读输入文件完毕之后的执行代码段-由END关键字标识
awk脚本的结构基本如下所示:
awk ‘ BEGIN{ print "start" } pattern { commands } END{ print "end" } file
awk命令也可以从stdin中读取。
awk脚本通常由3部分组成。BEGIN,END和带模式匹配选项的常见语句块。这3个部分都是可选项,在脚本中可省略任意部分。
awk命令的工作方式如下所注。
(1) 执行BEGIN { commands } 语句块中的语句。
(2) 从文件或stdin中读取一行,然后执行pattern { commands }。重复这个过程,直到文件全部被读取完毕。
(3) 当读至输入流末尾时,执行END { commands } 语句块。
BEGIN语句块在awk开始从输入流中读取行之前被执行。这是一个可选的语句块,诸如变量初始化、打印输出表格的表头等语句通常都可以写入BEGIN语句块中。
END语句块和BEGIN语句块类似。END语句块在awk从输入流中读取完所有的行之后即被执行。像打印所有行的分析结果这类汇总信息,都是在END语句块中实现的常见任务(例如,在比较过所有的行之后,打印出最大数)。它也是一个可选的语句块。
最重要的部分就是pattern语句块中的通用命令。这个语句块同样是可选的。如果不提供该语句块,则默认执行{ print },即打印所读取到的每一行。awk对于每一行,都会执行这个语句块。这就像一个用来读取行的while循环,在循环体中提供了相应的语句。
每读取一行,awk就会检查该行和提供的样式是否匹配。样式本身可以是正则表达式、条件语句以及行匹配范围等。如果当前行匹配该样式,则执行{ }中的语句。
样式是可选的。如果没有提供样式,那么awk就认为所有的行都是匹配的,并执行{ }中的语句。
(3)、BEGIN和END
Awk中定义了两个特殊的字段:BEGIN和END。
BEGIN用于在主输入循环之前执行,即在未读取输入文件行之前执行。
END则相反,用于在主输入循环之后执行,即在读取输入文件行完毕后执行。
计算文本行数
[[email protected] awk]# cat server1.txt
10.64.8.1 root 123
10.64.8.4 root 456
10.64.8.90 root 8888
[[email protected] awk]# cat server1.txt |awk ‘BEGIN{x=0}{x++}END{print x}‘
3
[[email protected] awk]#
[[email protected] awk]# cat server1.txt
10.64.8.1 root 123
10.64.8.4 root 456
10.64.8.90 root 8888
[[email protected] awk]# cat server1.txt |awk ‘END{print NR}‘
3
[[email protected] awk]#
这里只使用了END语句块。每读入一行,awk会将NR更新为对应的行号。当到达最后一行时,NR中的值就是最后一行的行号,于是,位于END语句块中的NR就包含了文件的行数。
我们通常将变量初始化语句(如var=0)以及打印文件头部的语句放入BEGIN语句块中。在END{}语句块中,往往会放入打印结果等语句。
(4)、awk执行三种方式
调用awk的方法与调用sed类似,也有三种方式,一种为shell命令行方式,另两种是将awk程序写入脚本文件,然后执行该脚本文件
在shell命令行输入命令调用awk
格式:awk [-F 域分隔符] ‘awk 程序段’ 输入文件
将awk程序段插入脚本文件,然后通过awk命令调用
与sed命令类似,awk也用-f选项表示调用awk脚本文件
格式为:awk -f awk脚本文件输入文件
将sed命令插入脚本文件后,设置脚本为可执行
设置可执行后,直接运行该脚本文件。
这种方式调用awk,awk脚本要以#!/bin/awk –f开头
格式:#./awk脚本文件输入文件
(5)、模式匹配
任何awk语句都由模式-pattern和动作-action组成。
模式是一组用户测试输入行是否需要执行动作的规则,动作是包含语句、函数和表达式的执行过程。
简言之,模式决定动作何时触发,动作执行对输入行的处理。
Awk模式匹配经常需要用到正则表达式,awk除支持基本正则表达式,还支持”?”和”+”两个扩展元字符,grep和sed并不支持。
示例1:
[[email protected] awk]# cat server.txt
10.64.8.1 root 123
10.64.8.2 root 456
10.64.8.90 root 8888
[[email protected] awk]# cat server.txt |awk ‘/90/‘
10.64.8.90 root 8888
[[email protected] awk]#
[[email protected] awk]# cat server.txt |awk ‘/90/{print "this is 90server" }‘
this is 90server
[[email protected] awk]# cat server.txt |awk ‘/^$/{print "this is a blank line" }‘
this is a blank line
this is a blank line
[[email protected] awk]#
示例采用的是第一种调用方式,单引号中间是awk命令。
该awk命令由两部分组成,以/符号分隔,^$部分是模式,花括号部分是动作,该命令表示一旦读入的输入文件行是空行,就打印”this is blank line”。
^$是正则表达式,表示空行,print表示该动作是打印操作。
示例2:
$ awk ‘NR < 5‘ # 行号小于5的行
$ awk ‘NR==1,NR==4‘ # 行号在1到5之间的行
$ awk ‘/linux/‘ # 包含样式linux的行(可以用正则表达式来指定模式)
$ awk ‘!/linux/‘ # 不包含包含模式为linux的行
(6)、记录和域
Awk认为输入文件是结构化的,awk将每个输入文件行定义为记录,行中的每个字符串定义为域,域之间用空格、tab键或其他符号进行分隔,分隔域的符号叫做分隔符。
两个或多个连续的空格或tab键当做一个分隔符来处理。
$在awk中叫做域操作符,域操作符后面跟数字或变量来标识域的位置。
$0打印全部域
$后面跟数字
[[email protected] awk]# cat server1.txt
10.64.8.1 root 123
10.64.8.2 root 456
10.64.8.90 root 8888
[[email protected] awk]# cat server1.txt |awk ‘{print $1}‘
10.64.8.1
10.64.8.2
10.64.8.90
[[email protected] awk]# cat server1.txt |awk ‘{print $0}‘
10.64.8.1 root 123
10.64.8.2 root 456
10.64.8.90 root 8888
[[email protected] awk]#
$后面跟表达式
[[email protected] awk]# cat server1.txt |awk ‘BEGIN {one=1;two=2}{print $one}‘
10.64.8.1
10.64.8.2
10.64.8.90
[[email protected] awk]# cat server1.txt |awk ‘BEGIN {one=1;two=2}{print $one,$two}‘
10.64.8.1 root
10.64.8.2 root
10.64.8.90 root
$后面跟字符串
[[email protected] awk]# cat server1.txt |awk ‘BEGIN {one=1;two=2}{print $one,$two,"papapa"}‘
10.64.8.1 root papapa
10.64.8.2 root papapa
10.64.8.90 root papapa
[[email protected] awk]# cat server1.txt |awk ‘BEGIN {one=1;two=2}{print $one,$two,"papapa",$(one+two)}‘
10.64.8.1 root papapa 123
10.64.8.2 root papapa 456
10.64.8.90 root papapa 8888
[[email protected] awk]#
$后面跟全局变量
[[email protected] awk]# cat server1.txt
10.64.8.1 root 123
10.64.8.2 root 456
10.64.8.90 root 8888
[[email protected] awk]# cat server1.txt |awk ‘{print $NF}‘
123
456
8888
[[email protected] awk]#
(7)、-F选项
Awk的默认域分隔符是空格。Tab键被看做是连续的空格键来处理。
使用-F选项来改变分隔符。
[[email protected] awk]# cat server2.txt
10.64.8.1,root,123
10.64.8.2,root,456
10.64.8.90,root,8888
[[email protected] awk]# cat server2.txt |awk -F‘,‘ ‘{print $1}‘
10.64.8.1
10.64.8.2
10.64.8.90
[[email protected] awk]# cat server2.txt |awk -F‘,‘ ‘{print $1,$3}‘
10.64.8.1 123
10.64.8.2 456
10.64.8.90 8888
[[email protected] awk]#
环境变量FS
FS变量也可以做域分隔,通过在BEGIN字段中设置FS的值来改变分隔符。
[[email protected] awk]# cat server2.txt
10.64.8.1,root,123
10.64.8.2,root,456
10.64.8.90,root,8888
[[email protected] awk]# cat server2.txt |awk ‘BEGIN {FS=","} {print $1,$3}‘
10.64.8.1 123
10.64.8.2 456
10.64.8.90 8888
[[email protected] awk]#
(8)、关系和布尔运算符
关系运算符
Awk定义了一组关系运算符用于awk模式匹配
< 小于
> 大于
<= 小于等于
>= 大于等于
== 等于
!= 不等于
~ 匹配正则表达式
!~ 不匹配正则表达式
[[email protected] awk]# cat /etc/passwd|awk -F‘:‘ ‘$1~/root/{print }‘
root:x:0:0:root:/root:/bin/bash
[[email protected] awk]# cat /etc/passwd|awk -F‘:‘ ‘$1=="root"{print }‘
root:x:0:0:root:/root:/bin/bash
[[email protected] awk]# cat /etc/passwd|awk -F‘:‘ ‘{if($1=="root")print }‘
root:x:0:0:root:/root:/bin/bash
[[email protected] awk]#
布尔运算符
为了进行多条件模式匹配,awk定义了三个布尔运算符表示多条件之间的关系
|| 逻辑或
&& 逻辑与
! 逻辑非
[[email protected] awk]# cat /etc/passwd|awk -F‘:‘ ‘{if($1=="root"||$1=="xiaoqq")print }‘
root:x:0:0:root:/root:/bin/bash
xiaoqq:x:502:502::/home/xiaoqq:/bin/bash
[[email protected] awk]#
(9)、表达式
与其他编程语言一样,awk表达式用于存储、操作和获取数据,一个awk表达式可以数值、字符常量、变量、操作符、函数和正则表达式自由组合而成。
awk算数运算符
+ 加
- 减
* 乘
/ 除
% 模
^或** 乘方
++x 在返回x值之前,x变量加1
x++ 在返回x值之后,x变量加1
计算文本中空行的行数
[[email protected] awk]# cat a1.txt
123
456
566
[[email protected] awk]# cat a1.txt |awk ‘/^$/{x=x+1}END{print x}‘
2
[[email protected] awk]#
[[email protected] awk]# cat a1.txt |grep "^$"|wc -l
2
计算学生平均分
[[email protected] awk]# cat a2.txt
tom 12 13 14
luci 20 2 19
xiaoming 18 60 7
[[email protected] awk]# cat a2.txt |awk ‘{total=$2+$3+$4;agv=total/3;print $1,agv}‘
tom 13
luci 13.6667
xiaoming 28.3333
[[email protected] awk]#
(10)、系统变量
awk定义来了很多内建变量用于设置环境信息,我们称他们为系统变量,这些变量可以分为两种
第一种用于改变awk的默认值,如域分隔符
第二种用于定义系统值,在处理文本时可以读取这些系统值,如记录中的域数量,当前记录数、当前文件名等,awk动态改变第2种系统变量的值。
awk环境变量极其意义
$n 当前记录的第n个域,域间由FS分割
$0 记录的所有域
ARGC 命令行参数的数量
ARGIND 命令行中当前文件的位置-以0开始标号
ARGV 命令行参数的数组
CONVFMT 数字转换格式
ENVIRON 环境变量关联数组
ERRNO 最后一个系统错误的描述
FIELDWIDTHS 字段宽度列表,以空格键分隔
FILENAME 当前文件名
FNR 浏览文件的记录数
FS 字段分隔符,默认是空格
IGNORECASE 布尔变量,如果为真,则进行忽略大小写的匹配
NF 当前记录中的域数量
NR 当前记录数
OFMT 数字的输出格式
OFS 输出域分隔符,默认是空格
ORS 输出记录分隔符,默认是换行符
RLENGTH 由match函数所匹配的字符串长度
RS 记录分隔符,默认是空格键
RSTART 由match函数所匹配的字符串的第一个位置
SUBSEP 数组下标分隔符、默认值是\034
(11)、格式化输出
print只提供了简单的输出功能。
当使用不带参数的print时,它会打印出当前行。关于print,需要记住两件重要的事情:
当print的参数是以逗号进行分隔时,参数打印时则以空格作为定界符。
在awk的print语句中,双引号是被当做拼接操作符(concatenation operator)使用的。
[[email protected] awk]# cat server1.txt
10.64.8.1 root 123
10.64.8.4 root 456
10.64.8.90 root 8888
[[email protected] awk]# cat server1.txt |awk ‘{print $1""$2}‘
10.64.8.1root
10.64.8.4root
10.64.8.90root
[[email protected] awk]# cat server1.txt |awk ‘{print $1":"$2":"$3}‘
10.64.8.1:root:123
10.64.8.4:root:456
10.64.8.90:root:8888
[[email protected] awk]#
printf
printf语句可以定义输出的格式,语法如下:
printf (格式控制符,参数)
printf语句包含两部分
第一部分,格式控制符,都以%符号开始,用于描述格式规范
第二部分,参数列表,比如变量名列表,与格式控制符相对应,是输出的对象。
格式控制符分为:
awk修饰符
- 左对齐
width 域的步长
.prec 小数点右边的位数
awk格式符
%c ASCII字符
%d 整型数
%e 浮点数,科学计数法
%f 浮点数
%o 八进制数
%s 字符串
%x 十六进制数
[[email protected] awk]# cat server2.txt
10.64.8.1,root,123
10.64.8.2,root,456
10.64.8.90,root,8888
[[email protected] awk]# cat server2.txt |awk ‘BEGIN{FS=","}{printf("\t%s\t\t%s\t\t%s\n",$1,$2,$3)}‘
10.64.8.1 root 123
10.64.8.2 root 456
10.64.8.90 root 8888
[[email protected] awk]#
(12)、内置函数
awk提供了强大的内置字符串函数,用于实现文本的字符串替换、查找以及分隔等功能
awk字符串函数列表
gsub(r,s)
在输入文件中用s替换r
[[email protected] awk]# cat server1.txt
10.64.8.1 root 123
10.64.8.2 root 456
10.64.8.90 root 8888
[[email protected] awk]# cat server1.txt |awk ‘gsub("10.64.8.1","10.64.8.8")‘
10.64.8.8 root 123
[[email protected] awk]#
gsub(r,s,t)
在t中用s替换r
[[email protected] awk]# cat server1.txt
10.64.8.1 root 123
10.64.8.2 root 456
10.64.8.90 root 8888
[[email protected] awk]# cat server1.txt |awk ‘gsub(/8.1/,"8.8",$1)‘
10.64.8.8 root 123
[[email protected] awk]#
index(s,t)
返回s中字符串第一个t的位置
[[email protected] awk]# cat server1.txt
10.64.8.1 root 123
10.64.8.4 root 456
10.64.8.90 root 8888
[[email protected] awk]# cat server1.txt |awk ‘{n=index($1,"4");print n}‘
5
5
5
[[email protected] awk]# cat server1.txt |awk ‘{n=index($2,"4");print n}‘
0
0
0
[[email protected] awk]# cat server1.txt |awk ‘{n=index($3,"4");print n}‘
0
1
0
[[email protected] awk]#
length(s)
返回s的长度
[[email protected] awk]# cat server1.txt
10.64.8.1 root 123
10.64.8.4 root 456
10.64.8.90 root 8888
[[email protected] awk]# cat server1.txt |awk ‘{n=length($3);print n}‘
3
3
4
[[email protected] awk]#
match(s,t)
测试s是否包含匹配t的字符串
t可以是一个正则表达式,若匹配成功,返回匹配t的首位置,若不成功,则返回0。
[[email protected] awk]# cat server1.txt
10.64.8.1 root 123
10.64.8.4 root 456
10.64.8.90 root 8888
[[email protected] awk]# cat server1.txt |awk ‘{n=match($3,/8/);print n}‘
0
0
1
split(r,s,t)
用分隔符t,将r分成序列s
t不指定的话,使用模式分隔符FS
[[email protected] awk]# echo "12:33:00"|awk ‘{split($1,a,":");print a[1],a[2],a[3]}‘
12 33 00
sub(r,s,t)
将t中第1次出现的r替换为s
[[email protected] awk]# echo "aaa"|awk ‘{sub("a","b",$1);print}‘
baa
substr(r,s)
返回字符串r中从s开始的后缀部分
[[email protected] awk]# echo -e "aaaaabcc8989\n7777b9999"|awk ‘{n=substr($1,8);print n}‘
c8989
99
substr(r,s,t)
返回字符串r中从s开始长度为t的后缀部分
[[email protected] awk]# echo -e "aaaaabcc8989\n7777b9999"|awk ‘{n=substr($1,8,2);print n}‘
c8
99
(13)、条件语句
awk条件语句和c语言的语法完全一样。
条件语句if的语法如下
if (条件表达式)
动作1
else
动作2
[[email protected] awk]# cat server1.txt
10.64.8.1 root 123
10.64.8.4 root 456
10.64.8.90 root 8888
[[email protected] awk]# cat server1.txt |awk ‘{if($1=="10.64.8.1")print $1; else print "a"}‘
10.64.8.1
a
a
#格式化awk语句
[[email protected] awk]# cat server1.txt |awk ‘{
if($1=="10.64.8.1"){
print $1
}
else {
print "a"
}
}
‘
10.64.8.1
a
a
[[email protected] awk]#
[[email protected] awk]# cat server1.txt |awk ‘{if($1=="10.64.8.1")print $1}‘
10.64.8.1
[[email protected] awk]#
(14)、循环
循环语句有三种:while、do while、for
While循环语法如下:
While (条件表达式)
动作
do while语法如下
do
动作
While (条件表达式)
for循环语法如下:
for (设置计数器初值;测试计数器;计数器变化)
动作
例如
for(i=0;i<10;i++) { print $i ; }
或者
for(i in array) { print array[i]; }
(15)、数组
数组是用于存储一些列值的变量,这些值之间通常是有联系的,可通过索引来访问数组的值,索引需要用中括号括起,数组的基本格式为:
array[index]=value
awk数组无须定义数组类型和大小,而可以直接赋值后使用。
1)、关联数组
关联数组是指数组的索引可以是字符串,也可以是数字。
在大部分编程语言中,数组的索引只能是数字,数组表示了存储值的一系列地址,数组索引是存储地址的顺序来决定的,如c语言中array[0]表示数组的起始地址。
而关联数组在索引和数组元素值之间建立器关联,对每一个数组元素,awk自动维护了一对值:索引和数组元素值。
关联数组的值无须以连续的地址进行存储,因此,关联数组即便可以使用数字作为索引,但是该数字索引并表示数组存储地址的信息。
Awk的所有数组都是关联数组,这是awk数组和其他大部分编程语言数组的本质区别。
关联数组访问
Awk特别定义了一种for循环用来访问关联数组,语法如下
for (variable in array)
do something with array[variable]
array是已定义的数组名,variable是任意指定的变量,可以看做是for循环中定义的临时变量。
关键字in也可用在条件表达式中判断元素是否在数组中,条件表达式格式为:
index in array
如果array[index]存在,则返回1,否则返回0.
awk ‘BEGIN{
a["index1"]=11;
a["index2"]=22;
for(i in a){
print i,a[i]
}
}‘
[[email protected] awk]# awk ‘BEGIN{
> a["index1"]=11;
> a["index2"]=22;
> for(i in a){
> print i,a[i]
> }
> }‘
index1 11
index2 22
[[email protected] awk]#
2)、split函数
用分隔符t,将r分成序列s
t不指定的话,使用模式分隔符FS
echo "12 23 44"|awk ‘{
split($0,a," ")
print a[1],a[2],a[3]
for(i in a){
print a[i]
}
}
‘
[[email protected] awk]#
[[email protected] awk]# echo "12 23 44"|awk ‘{
> split($0,a," ")
> print a[1],a[2],a[3]
> for(i in a){
> print a[i]
> }
> }
> ‘
12 23 44
12
23
44
3)、数组形式的系统变量
ARGV-
echo "12:23:00"|awk -F‘:‘ ‘{
for (i in ARGV){
print ARGV[i]
}
print ARGC
}
‘
[[email protected] awk]# echo "12:23:00"|awk -F‘:‘ ‘{
> for (i in ARGV){
> print ARGV[i]
> }
> print ARGC
>
> }
> ‘
awk
1
[[email protected] awk]#
ENVIRON
awk ‘
BEGIN {
for (i in ENVIRON) {
print i "=" ENVIRON[i]
}
}
‘
[[email protected] awk]# awk ‘
> BEGIN {
> for (i in ENVIRON) {
> print i "=" ENVIRON[i]
> }
> }
> ‘
TERM=vt100
G_BROKEN_FILENAMES=1
SHLVL=1
PWD=/root/shell/test/awk
HISTTIMEFORMAT=%F %T
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/mysql-5.7.17/bin/:/root/bin
OLDPWD=/root/shell/test
AWKPATH=.:/usr/share/awk
_=/bin/awk
LANG=zh_CN.UTF-8
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:
SSH_CONNECTION=10.8.41.231 53019 172.23.54.84 22
MAIL=/var/spool/mail/root
HOSTNAME=Test01
HISTFILE=/usr/share/.history/root/10.8.41.231.history.20170907_193512
USER=root
HISTFILESIZE=40000
HISTSIZE=4000
SSH_TTY=/dev/pts/1
SHELL=/bin/bash
LESSOPEN=||/usr/bin/lesspipe.sh %s
LOGNAME=root
HOME=/root
HISTCONTROL=ignoredups
SSH_CLIENT=10.8.41.231 53019 22
[[email protected] awk]#
(16)、将外部变量值传递给awk
借助选项 -v,我们可以将外部值(并非来自stdin)传递给awk:
$ VAR=10000
$ echo | awk -v VARIABLE=$VAR ‘{ print VARIABLE }‘
10000
还有另一种灵活的方法可以将多个外部变量传递给awk,例如:
$ var1="Variable1" ; var2="Variable2"
$ echo | awk ‘{ print v1,v2 }‘ v1=$var1 v2=$var2
Variable1 Variable2
当输入来自于文件而非标准输入时,使用下列命令:
$ awk ‘{ print v1,v2 }‘ v1=$var1 v2=$var2 filename
在上面的方法中,变量之间用空格分隔,以键-值对的形式(v1=$var1 v2=$var2)作为awk的命名行参数紧随在BEGIN、{}和END语句块之后。
(17)、用getline读取行
awk通常默认读取一个文件的所有行。如果只想读取某一行,可以使用getline函数。有时候,我们需要从BEGIN语句块中读取第一行。
语法:
getline var。
变量var就包含了特定行的内容。如果调用不带参数的getline,我们可以用 $0、$1和$2访问文本行的内容。
[[email protected] awk]# seq 5
1
2
3
4
5
[[email protected] awk]# seq 5|awk ‘BEGIN{getline}{print "a",$0}‘
a 2
a 3
a 4
a 5
[[email protected] awk]# seq 5|awk ‘BEGIN{getline;print}{print "a",$0}‘
1
a 2
a 3
a 4
a 5
[[email protected] awk]# seq 5|awk ‘BEGIN{getline;print $0}{print "a",$0}‘
1
a 2
a 3
a 4
a 5
[[email protected] awk]# seq 5|awk ‘BEGIN{getline var;print var }{print "a",$0}‘
1
a 2
a 3
a 4
a 5
[[email protected] awk]#
(18)、awk中运行shell命令
将命令的输出结果读入变量output的语法如下:
"command" | getline output ;
在下面的代码中,echo会生成一个空白行。变量cmdout包含命令grep root /etc/passwd的输出,该命令会打印出包含root的行。
[[email protected] awk]# echo | awk ‘{"echo 123"|getline var;print var }‘
123
[[email protected] awk]# echo | awk ‘{"grep root /etc/passwd"|getline var;print var }‘
root:x:0:0:root:/root:/bin/bash
[[email protected] awk]#
通过使用getline,我们将外部shell命令的输出读入变量cmdout。
本文出自 “微小信的运维之道” 博客,请务必保留此出处http://weixiaoxin.blog.51cto.com/13270051/1963639
以上是关于Linux Shell学习--awk命令详解的主要内容,如果未能解决你的问题,请参考以下文章
shell命令三剑客之awk命令详解,cut命令,linux里记录行踪(操作记录)