linux系统之文本格式化工具awk
2014-04-06 22:36
369 查看
一、文本处理工具
grep、sed和awk都是文本处理工具,虽然都是文本处理工具但却都有各自的优缺点,一种文本处理命令是不能被另一个完全替换的,否则也不会出现三个文本处理命令了。只不过,相比较而言,sed和awk功能更强大而已,且已独立成一种语言来介绍。
grep:文本过滤器,如果仅仅是过滤文本,可使用grep,其效率要比其他的高很多;sed:Stream EDitor,流编辑器,默认只处理模式空间,不处理原数据,如果你处理的数据是针对行进行处理的,可以使用sed;
awk:报告生成器,格式化以后显示。如果对处理的数据需要生成报告之类的信息,或者你处理的数据是按列进行处理的,最好使用awk。
二、awk可以完成的一些功能
将文本文件看做由记录和字段组成的文本数据库
使用变量操作数据库
使用算术和字符串操作符
使用普通的程序设计结构,例如循环和条件
生帮格式化报告
定义函数
从脚本中执行unix命令
处理unix命令的结果
更加巧妙的处理命令行的参数
更容易地处理多个输入流
三、语法格式
-F fs or --field-separator fs:
指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:
-v 选项定义的变量在脚本运行之前即存在,可以在脚本的 BEGIN 流程中被调用;
2、awk的输出:print和printf
⑴、print的使用格式:
print item1, item2, ...
要点:
①、各项目之间使用逗号隔开,而输出时则以空白字符分隔;
②、输出的item可以为字符串或数值、当前记录的字段(如$1)、变量或awk的表达式;数值会先转换为字符串,而后再输出;
③、print命令后面的item可以省略,此时其功能相当于print $0, 因此,如果想输出空白行,则需要使用print "";
注意,在AWK中,$表示字段,用户变量不需要加$,这是AWK与shell或者Perl不同之处!在shell中,变量定义时不加$,再次引用时则需要用$,而在Perl中,无论定义和引用时都需要加$ (Perl中$表示标量,另有@和%符号表示数组和Hash变量)。
实例
⑵、printf的使用格式
printf format, item1, item2, ...
format格式的指示符都以%开头,后跟一个字符,
%c
转换数字成ASCII,如printf "%c", 67结果为C。
%d, %i
打印十进制整数,如printf "%dn", 6.745结果为6。
%e, %E
转换数字为科学(指数)符号,如printf "%4.3en", 6745结果为6.745e+03。
%f
以浮点表示法打印数字,如 printf "%4.3f\n", 6745结果为6745.0000000
%s
打印字符串,如printf "%10s\n", 6745结果为十个空格加6745。
可更改的格式:
N$
位置指示符,可调整字符串的输出位置。printf "%s %s %s\n", "I", "lOVE","YOU"输出为:I LOVE YOU,我们调整一下位置,printf "%3$s %2$s %1$s\n", "YOU", "LOVE","I",输出结果为:I LOVE YOU
修饰符
N: 显示宽度;
-: 左对齐;+:右对齐(也可以显示数值符号正负之用);
3、模式和操作
⑴、模式可以是以下任意一个:
/正则表达式/:使用通配符的扩展集。
关系表达式:可以用下面运算符表中的关系运算符进行操作,可以是字符串或数字的比较,如$2>%1选择第二个字段比第一个字段长的行。
模式匹配表达式:用运算符~(匹配)和~!(不匹配)。
模式,模式:指定一个行的范围。该语法不能包括BEGIN和END模式。
BEGIN:让用户指定在第一条输入记录被处理之前所发生的动作,通常可在这里设置全局变量。
END:让用户在最后一条输入记录被读取之后发生的动作。
⑵、操作由一人或多个命令、函数、表达式组成,之间由换行符或分号隔开,并位于大括号内。主要有四部份:
变量或数组赋值
输出命令
内置函数
控制流命令
4、变量
⑴、awk内置变量之记录变量
注:
从$1,$2一直到$NF,整行用$0标,如果$0被赋予新值,所有的$1,$2...和NF都将被重新计算。同样,若$i被改变,$0将用OFS重新计算。
⑵、awk内置变量之数据变量
NR用法
NF用法(默认以空格分隔)
FNR用法
ARGV用法
之二
FILENAME用法
ENVIRON用法
注:
ARGV数组由ARGV[0]....ARGV[ARGC-1]组成,第一个元素是0而不是1,这与AWK中的般数组不同
ENVIROND数组在shell与AWK的交互中非常有用,使用ENVIRON["PARA_NAME"]来获取环境变量$PARA_NAME的值,其中引号“”不可少!
5、标准输出与重定向
⑴、输出重定向
print items > output-fileprint items >> output-fileprint items | command⑵、特殊文件描述符:/dev/stdin:标准输入/dev/sdtout: 标准输出/dev/stderr: 错误输出/dev/fd/N: 某特定文件描述符,如/dev/stdin就相当于/dev/fd/0;实例:
6、awk的操作符:
⑴、算术操作符:-x: 负值+x: 转换为数值;x^y: x**y: 次方x*y: 乘法x/y:除法x+y:x-y:x%y:
实例
⑵、字符串操作符:只有一个,而且不用写出来,用于实现字符串连接;⑶、 赋值操作符:=+=-=*=/=%=^=**=++--需要注意的是,如果某模式为=号,此时使用/=/可能会有语法错误,应以/[=]/替代;
⑷、布尔值awk中,任何非0值或非空字符串都为真,反之就为假;⑸、 比较操作符:x < y True if x is less than y. x <= y True if x is less than or equal to y. x > y True if x is greater than y. x >= y True if x is greater than or equal to y. x == y True if x is equal to y. x != y True if x is not equal to y. x ~ y True if the string x matches the regexp denoted by y. x !~ y True if the string x does not match the regexp denoted by y. subscript in array True if the array array has an element with the subscript subscript.⑺、表达式间的逻辑关系符:&&||
实例:
⑻、条件表达式:selector?if-true-exp:if-false-expif selector; then if-true-expelse if-false-expfi实例
⑼、函数调用:
function_name(para1,para2)7、控制语句
⑴、 if-else语法:
if (condition) {then-body} else {[ else-body ]}
实例:
⑵、 while
语法:
while (condition){statement1; statment2; ...}
实例:
⑶、do-while 至少执行一次循环体,不管条件满足与否
语法:
do {statement1, statement2, ...} while (condition)
实例:
⑷、for
语法:for ( variable assignment; condition; iteration process) { statement1, statement2, ...}实例:
for循环还可以用来遍历数组元素:
语法:
for (i in array) {statement1, statement2, ...}
实例:
⑸、 case
语法:switch (expression) { case VALUE or /REGEXP/: statement1, statement2,... default: statement1, ...}⑹、 break 和 continue常用于循环或case语句中⑺、 next提前结束对本行文本的处理,并接着处理下一行;例如,下面的命令将显示其ID号为奇数的用户:实例:
9、awk中使用数组
⑴、 数组array[index-expression]index-expression可以使用任意字符串;需要注意的是,如果某数据组元素事先不存在,那么在引用其时,awk会自动创建此元素并初始化为空串;因此,要判断某数据组中是否存在某元素,需要使用index in array的方式。要遍历数组中的每一个元素,需要使用如下的特殊结构:语法
for (var in array) { statement1, ... }
其中,var用于引用数组下标,而不是元素值;实例:
⑵、 删除数组变量
从关系数组中删除数组索引需要使用delete命令。使用格式为:delete array[index]10、awk的内置函数split(string, array [, fieldsep [, seps ] ])功能:将string表示的字符串以fieldsep为分隔符进行分隔,并将分隔后的结果保存至array为名的数组中;数组下标为从1开始的序列;实例:
length([string])
功能:返回string字符串中字符的个数;substr(string, start [, length])功能:取string字符串中的子串,从start开始,取length个;start从1开始计数;
system(command)
功能:执行系统command并将结果返回至awk命令
systime()功能:systime函数返回从1970年1月1日开始到当前时间(不计闰年)的整秒数
tolower(s)功能:将s中的所有字母转为小写toupper(s)功能:将s中的所有字母转为大写
================================完===================================================
PS:
awk简单应用到此结束!
本文出自 “和风细雨” 博客,请务必保留此出处http://essun.blog.51cto.com/721033/1391320
grep、sed和awk都是文本处理工具,虽然都是文本处理工具但却都有各自的优缺点,一种文本处理命令是不能被另一个完全替换的,否则也不会出现三个文本处理命令了。只不过,相比较而言,sed和awk功能更强大而已,且已独立成一种语言来介绍。
grep:文本过滤器,如果仅仅是过滤文本,可使用grep,其效率要比其他的高很多;sed:Stream EDitor,流编辑器,默认只处理模式空间,不处理原数据,如果你处理的数据是针对行进行处理的,可以使用sed;
awk:报告生成器,格式化以后显示。如果对处理的数据需要生成报告之类的信息,或者你处理的数据是按列进行处理的,最好使用awk。
二、awk可以完成的一些功能
将文本文件看做由记录和字段组成的文本数据库
使用变量操作数据库
使用算术和字符串操作符
使用普通的程序设计结构,例如循环和条件
生帮格式化报告
定义函数
从脚本中执行unix命令
处理unix命令的结果
更加巧妙的处理命令行的参数
更容易地处理多个输入流
三、语法格式
# awk [options] 'script' file1 file2, ... # awk [options] 'PATTERN { action }' file1 file2, ..1、选项
-F fs or --field-separator fs:
指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:
#awk -F: '/root/{print $1,$NF}' /etc/passwd #awk -F: '/root/{print $1$NF}' /etc/passwd #awk -F: '/root/{print $1 $NF}' /etc/passwd #awk -F: '/root/{print $1"#"$NF}' /etc/passwd
-v 选项定义的变量在脚本运行之前即存在,可以在脚本的 BEGIN 流程中被调用;
2、awk的输出:print和printf
⑴、print的使用格式:
print item1, item2, ...
要点:
①、各项目之间使用逗号隔开,而输出时则以空白字符分隔;
②、输出的item可以为字符串或数值、当前记录的字段(如$1)、变量或awk的表达式;数值会先转换为字符串,而后再输出;
③、print命令后面的item可以省略,此时其功能相当于print $0, 因此,如果想输出空白行,则需要使用print "";
注意,在AWK中,$表示字段,用户变量不需要加$,这是AWK与shell或者Perl不同之处!在shell中,变量定义时不加$,再次引用时则需要用$,而在Perl中,无论定义和引用时都需要加$ (Perl中$表示标量,另有@和%符号表示数组和Hash变量)。
实例
⑵、printf的使用格式
printf format, item1, item2, ...
format格式的指示符都以%开头,后跟一个字符,
%c
转换数字成ASCII,如printf "%c", 67结果为C。
%d, %i
打印十进制整数,如printf "%dn", 6.745结果为6。
%e, %E
转换数字为科学(指数)符号,如printf "%4.3en", 6745结果为6.745e+03。
%f
以浮点表示法打印数字,如 printf "%4.3f\n", 6745结果为6745.0000000
%s
打印字符串,如printf "%10s\n", 6745结果为十个空格加6745。
可更改的格式:
N$
位置指示符,可调整字符串的输出位置。printf "%s %s %s\n", "I", "lOVE","YOU"输出为:I LOVE YOU,我们调整一下位置,printf "%3$s %2$s %1$s\n", "YOU", "LOVE","I",输出结果为:I LOVE YOU
修饰符
N: 显示宽度;
-: 左对齐;+:右对齐(也可以显示数值符号正负之用);
3、模式和操作
⑴、模式可以是以下任意一个:
/正则表达式/:使用通配符的扩展集。
关系表达式:可以用下面运算符表中的关系运算符进行操作,可以是字符串或数字的比较,如$2>%1选择第二个字段比第一个字段长的行。
模式匹配表达式:用运算符~(匹配)和~!(不匹配)。
模式,模式:指定一个行的范围。该语法不能包括BEGIN和END模式。
BEGIN:让用户指定在第一条输入记录被处理之前所发生的动作,通常可在这里设置全局变量。
END:让用户在最后一条输入记录被读取之后发生的动作。
⑵、操作由一人或多个命令、函数、表达式组成,之间由换行符或分号隔开,并位于大括号内。主要有四部份:
变量或数组赋值
输出命令
内置函数
控制流命令
4、变量
⑴、awk内置变量之记录变量
FS: field separator | 读取文件本时,所使用字段分隔符 |
RS: Record separator | 输入文本信息所使用的换行符 |
OFS: Output Filed Separator | 输出字段分隔符(默认值是一个空格) |
ORS:Output Row Separator | 输出记录分隔符(默认值是一个换行符) |
注:
从$1,$2一直到$NF,整行用$0标,如果$0被赋予新值,所有的$1,$2...和NF都将被重新计算。同样,若$i被改变,$0将用OFS重新计算。
⑵、awk内置变量之数据变量
NR: The number of input records | awk命令所处理的记录数;如果有多个文件,这个数目会把处理的多个文件中行统一计数 |
NF:Number of Field | 当前记录的field个数 |
FNR | 当前文件的相对记录数 |
ARGV | 数组,保存命令行本身这个字符串,如awk '{print $0}' a.txt b.txt这个命令中,ARGV[0]保存awk,ARGV[1]保存a.txt |
ARGC | awk命令的参数的个数 |
FILENAME | awk命令所处理的文件的名称 |
ENVIRON | 当前shell环境变量及其值的关联数组 |
NF用法(默认以空格分隔)
FNR用法
ARGV用法
之二
FILENAME用法
ENVIRON用法
注:
ARGV数组由ARGV[0]....ARGV[ARGC-1]组成,第一个元素是0而不是1,这与AWK中的般数组不同
ENVIROND数组在shell与AWK的交互中非常有用,使用ENVIRON["PARA_NAME"]来获取环境变量$PARA_NAME的值,其中引号“”不可少!
5、标准输出与重定向
⑴、输出重定向
print items > output-fileprint items >> output-fileprint items | command⑵、特殊文件描述符:/dev/stdin:标准输入/dev/sdtout: 标准输出/dev/stderr: 错误输出/dev/fd/N: 某特定文件描述符,如/dev/stdin就相当于/dev/fd/0;实例:
# awk -F" " '{printf "%-15s %i\n",$1,$3 > "/dev/stderr" }' /etc/issue # awk -F" " '{printf "%-15s %i\n",$1,$3 > "/dev/null" }' /etc/issue
6、awk的操作符:
⑴、算术操作符:-x: 负值+x: 转换为数值;x^y: x**y: 次方x*y: 乘法x/y:除法x+y:x-y:x%y:
实例
⑵、字符串操作符:只有一个,而且不用写出来,用于实现字符串连接;⑶、 赋值操作符:=+=-=*=/=%=^=**=++--需要注意的是,如果某模式为=号,此时使用/=/可能会有语法错误,应以/[=]/替代;
⑷、布尔值awk中,任何非0值或非空字符串都为真,反之就为假;⑸、 比较操作符:x < y True if x is less than y. x <= y True if x is less than or equal to y. x > y True if x is greater than y. x >= y True if x is greater than or equal to y. x == y True if x is equal to y. x != y True if x is not equal to y. x ~ y True if the string x matches the regexp denoted by y. x !~ y True if the string x does not match the regexp denoted by y. subscript in array True if the array array has an element with the subscript subscript.⑺、表达式间的逻辑关系符:&&||
实例:
⑻、条件表达式:selector?if-true-exp:if-false-expif selector; then if-true-expelse if-false-expfi实例
⑼、函数调用:
function_name(para1,para2)7、控制语句
⑴、 if-else语法:
if (condition) {then-body} else {[ else-body ]}
实例:
#awk '{if ($3==0) {print $1, "Adminitrator";} else { print $1,"Common User"}}' /etc/passwd #awk -F: '{if ($1=="root") print $1, "Admin"; else print $1, "Common User"}' /etc/passwd #awk -F: '{if ($1=="root") printf "%-15s: %s\n", $1,"Admin"; else printf "%-15s: %s\n", $1, "Common User"}' /etc/passwd #awk -F: -v sum=0 '{if ($3>=500) sum++}END{print sum}' /etc/passwd
⑵、 while
语法:
while (condition){statement1; statment2; ...}
实例:
#awk -F: '{i=1;while (i<=3) {print $i;i++}}' /etc/passwd #awk -F: '{i=1;while (i<=NF) { if (length($i)>=4) {print $i}; i++ }}' /etc/passwd #awk '{i=1;while (i<=NF) {if ($i>=20000) print $i; i++}}' random.txt #random.txt文件的内容为一堆随机数。
⑶、do-while 至少执行一次循环体,不管条件满足与否
语法:
do {statement1, statement2, ...} while (condition)
实例:
#awk 'BEGIN{ sum=0; i=0; do{ sum+=i; i++; }while(i<=100) print sum;}'
⑷、for
语法:for ( variable assignment; condition; iteration process) { statement1, statement2, ...}实例:
#awk -F: '{for(i=1;i<=3;i++) { if (length($i)>=8) {print $i}}}' /etc/passwd
for循环还可以用来遍历数组元素:
语法:
for (i in array) {statement1, statement2, ...}
实例:
#awk -F: '$NF!~/^$/{BASH[$NF]++}END{for(A in BASH){printf "%-15s:%i\n",A,BASH[A]}}' /etc/passwd
⑸、 case
语法:switch (expression) { case VALUE or /REGEXP/: statement1, statement2,... default: statement1, ...}⑹、 break 和 continue常用于循环或case语句中⑺、 next提前结束对本行文本的处理,并接着处理下一行;例如,下面的命令将显示其ID号为奇数的用户:实例:
# awk -F: '{if($3%2==0) next;print $1,$3}' /etc/passwd
9、awk中使用数组
⑴、 数组array[index-expression]index-expression可以使用任意字符串;需要注意的是,如果某数据组元素事先不存在,那么在引用其时,awk会自动创建此元素并初始化为空串;因此,要判断某数据组中是否存在某元素,需要使用index in array的方式。要遍历数组中的每一个元素,需要使用如下的特殊结构:语法
for (var in array) { statement1, ... }
其中,var用于引用数组下标,而不是元素值;实例:
#netstat -ant | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
⑵、 删除数组变量
从关系数组中删除数组索引需要使用delete命令。使用格式为:delete array[index]10、awk的内置函数split(string, array [, fieldsep [, seps ] ])功能:将string表示的字符串以fieldsep为分隔符进行分隔,并将分隔后的结果保存至array为名的数组中;数组下标为从1开始的序列;实例:
# netstat -ant | awk '/:80\>/{split($5,clients,":");IP[clients[1]]++}END{for(i in IP){print IP[i],i}}' | sort -rn | head -50 # netstat -tan | awk '/:80\>/{split($5,clients,":");ip[clients[4]]++}END{for(a in ip) print ip[a],a}' | sort -rn | head -50 # df -lh | awk '!/^File/{split($5,percent,"%");if(percent[1]>=20){print $1}}'
length([string])
功能:返回string字符串中字符的个数;substr(string, start [, length])功能:取string字符串中的子串,从start开始,取length个;start从1开始计数;
# tail -10 /etc/passwd |awk -F: '{print substr($1,1,6)}'
system(command)
功能:执行系统command并将结果返回至awk命令
# awk 'BEGIN{print system("ls -l")}'
systime()功能:systime函数返回从1970年1月1日开始到当前时间(不计闰年)的整秒数
tolower(s)功能:将s中的所有字母转为小写toupper(s)功能:将s中的所有字母转为大写
# awk 'BEGIN{s="acl";print toupper(s)}'
================================完===================================================
PS:
awk简单应用到此结束!
本文出自 “和风细雨” 博客,请务必保留此出处http://essun.blog.51cto.com/721033/1391320
相关文章推荐
- Linux系统上的文本处理工具之sed
- Linux学习--第二天--分区、格式化、系统安装、vmware、远程管理工具
- linux-awk【行扫描文本:样式扫描与处理工具】
- linux文本分析工具awk解读
- Linux的文本处理工具浅谈-awk sed grep
- linux基础--awk文本分析工具详解
- 格式化文本数据抽取工具awk
- mac 系统的Numbers格式化linux中awk后的结果
- 【Linux】 字符串和文本处理工具 grep & sed & awk
- linux 文本分析工具---awk命令(7/1)
- Linux下文本分析工具awk的简单使用
- linux系统下的文本处理,awk,sed
- Perf -- Linux下的系统性能调优工具
- Linux系统补丁工具patch AND diff
- linux 磁盘管理四部曲——(2)管理分区,文件系统类型格式化
- Linux下的系统性能调优工具——Perf
- windows和linux系统下数据传输工具——tftpd32使用说明
- 管理员必备的20个Linux系统监控工具
- Perf -- Linux下的系统性能调优工具,第 1 部分
- linux上的一些系统监测工具简介