【Bash百宝箱】awk
来源:互联网 发布:网络直播议论文 编辑:程序博客网 时间:2024/05/16 08:01
awk是一个强大的文本分析工具,从文件或管道中每次读取一行,默认以空格为分隔符把输入分割成若干字段,然后进行处理,一般格式如下:
awk [OPTIONS] 'patterns{actions}' files
分隔符
1、“-F value”设置每行文本的分隔符为value,默认是空格。文本行被分割后的各字段由数字来访问,从1开始,0表示整行文本。如下例子中的“print”是个命令,用于输出。
$ cat myfile 123 456 789abc:def:ghi$ awk '{print $1}' myfile 123abc:def:ghi$ awk -F : '{print $1}' myfile 123 456 789abc
从文件中读取参数
2、“-f file”从文件file中读取awk参数,可通过多个“-f”指定多个文件。
$ cat myfile 123 456 789abc:def:ghi$ cat myinput {print $1}$ awk -f myinput myfile 123abc:def:ghi
设置内建变量
3、“-v var=value”设置awk内建变量var的值为value。如下例子中的变量“RS”为输入分隔符,默认为“\n”。
$ cat myfile 123 456 789abc:def:ghi$ awk '{print $1}' myfile123abc:def:ghi$ awk -v RS='\n' '{print $1}' myfile123abc:def:ghi$ awk -v RS='5' '{print $1}' myfile1236
选项结束标记
4、“–”表示awk选项OPTIONS结束,其后若还有其它选项则出错。
$ cat myfile 123 456 789abc:def:ghi$ awk -F : '{print $1}' myfile 123 456 789abc$ awk -F : -- '{print $1}' myfile123 456 789abc
mawk扩展选项
5、“-W”是mawk提供的对awk的扩展选项,适用于awk,有如下6种。
-W version 输出版本号、版权和编译限制,简写为“-Wv”。-W dump 输出程序对应的汇编代码,简写为“-Wd”。-W interactive 简写为“-Wi”。-W exec file 从文件file中读取awk参数,简写为“-We file”。-W sprintf=num 设置sprintf的buffer长度。-W posix-space 强制mawk认为“\n”不是空格。
程序结构
6、awk程序是一系列的“patterns{actions}”组合,其中patterns表示以什么样的模式去匹配文本行,actions表示对匹配的文本行执行什么动作,两者可省其一,缺省patterns表示匹配所有行,缺省actions表示“{print}”。patterns可以是单个表达式或者逗号分隔的多个表达式,有两个特殊模式BEGIN、END,表示对第一行文本执行命令前、最后一行文本执行命令后所要执行的内容,因此这两者不能缺省actions。表达式以换行符或逗号分隔,长表达式可使用符号“\”进行续行,多个表达式可以放在一对花括号内为一组,符号“#”为注释符,支持“&&”和“||”以及如下语句。
if ( expr ) statementif ( expr ) statement else statementwhile ( expr ) statementdo statement while ( expr )for ( opt_expr ; opt_expr ; opt_expr ) statementfor ( var in array ) statementcontinuebreak
下面是一个简单的例子,文件myfile中有3行文本,每行文本以冒号分隔,共两个字段,分别表示单词字符数和单词,awk程序myinput用变量num统计所有的单词字符数,单词字符数大于5时打印当前文本行内容,命令“print”输出的内容无分隔符,逗号表示输出的内容以空格分隔。
$ cat myfile 5:apple4:pear6:banana$ cat myinputBEGIN {num=0}{ num+=$1 if ($1>5) print $0}END {print "total:",num}$ awk -F : -f myinput myfile 6:bananatotal: 15
awk语法与C类似,支持如下操作符:
assignment = += -= *= /= %= ^= conditional ? : logical or || logical and && array membership in matching ~ !~ relational < > <= >= == != concatenation (no explicit operator) add ops + - mul ops * / % unary + - logical not ! exponentiation ^ inc and dec ++ -- (both post and pre) field $
数据类型
7、awk中有两种基本数据类型,数字和字符串。数字可以是整数(-2)、小数(1.08)和科学计数(-1.1e4、.28E-3)。字符串放在双引号中,支持如下转义字符:
\\ \ \" " \a alert, ascii 7 \b backspace, ascii 8 \t tab, ascii 9 \n newline, ascii 10 \v vertical tab, ascii 11 \f formfeed, ascii 12 \r carriage return, ascii 13 \ddd 1, 2 or 3 octal digits for ascii ddd \xhh 1 or 2 hex digits for ascii hh
诸如“15”等可以被当作数字或字符串,awk会根据实际情况自动转换为合适的类型,如下例子中的格式化输出命令“printf”。
$ cat myfile 5:apple4:pear6:banana$ cat myinputBEGIN {num=0}{ num+=$1 if ($1>5) printf("%d\n", num) if ($1>5) printf("%s\n", num)}END {print "total:",num}$ awk -F : -f myinput myfile1515total: 15
正则表达式
8、正则表达式放在两个斜线之间,格式如下:
expr ~ /r/expr !~ /r/
awk命令中如下两种正则形式是等效的:
/r/ { action }$0 ~ /r/ { action }
awk正则支持普通字符、转义字符和如下特殊符号:
^ $ . [ ] | ( ) * + ?
如下使用了正则的例子:
$ cat myfile 5:apple4:pear6:banana$ awk '/banana/' myfile 6:banana$ awk '!/banana/' myfile 5:apple4:pear
数组
9、awk支持数组,例子如下。
$ cat myfile 5:apple4:pear6:banana$ cat myinput {array[$1]=$2}END {for(var in array) print var,array[var]}$ awk -F : -f myinput myfile 4 pear5 apple6 banana
使用delete删除数组中的元素:
$ cat myfile 5:apple4:pear6:banana$ cat myinput {array[$1]=$2}END {delete array[5]; for(var in array) print var,array[var]}$ awk -F : -f myinput myfile 4 pear6 banana
内建变量
10、awk支持如下内建变量。
ARGC number of command line arguments. ARGV array of command line arguments, 0..ARGC-1. CONVFMT format for internal conversion of numbers to string, initially = "%.6g". ENVIRON array indexed by environment variables. An environ‐ment string, var=value is stored as ENVIRON[var] = value. FILENAME name of the current input file. FNR current record number in FILENAME. FS splits records into fields as a regular expression. NF number of fields in the current record. NR current record number in the total input stream. OFMT format for printing numbers; initially = "%.6g". OFS inserted between fields on output, initially = " ". ORS terminates each record on output, initially = "\n". RLENGTH length set by the last call to the built-in function, match(). RS input record separator, initially = "\n". RSTART index set by the last call to match(). SUBSEP used to build multiple array subscripts, initially = "\034".
访问内建变量不要使用美元符号,如下例子:
$ cat myfile hello sed5:apple4:pear6:banana$ awk -F : '{print ARGC}' myfile 2222$ awk -F : '{print ARGV[0],ARGV[1]}' myfile awk myfileawk myfileawk myfileawk myfile$ awk -F : '{print CONVFMT}' myfile %.6g%.6g%.6g%.6g$ awk -F : '{print FILENAME}' myfile myfilemyfilemyfilemyfile$ awk -F : '{print FNR}' myfile 1234$ awk -F : '{print FS}' myfile ::::$ awk -F : '{print NF}' myfile 1222$ awk -F : '{print NR}' myfile 1234$ awk -F : '{print OFMT}' myfile %.6g%.6g%.6g%.6g
内建函数
11、awk支持如下内建函数。
字符串处理函数——gsub(r,s,t) 把变量t中与正则r匹配的所有内容替换为字符串s,返回匹配的个数。gsub(r,s) 把当前行(即$0)中与正则r匹配的所有内容替换为字符串s,返回匹配的个数。index(s,t) 返回子串t在字符串s中的位置,从1开始。length(s) 返回字符串s的字符个数。match(s,r) 返回字符串s中与正则r第一个匹配的最长字符串的位置。split(s,A,r) 把r作为分隔符分割字符串s,结果保存到数组A中,返回分割的字段个数。split(s,A) 把内建变量FS的值作为分隔符分割字符串s,结果保存到数组A中,返回分割的字段个数。sprintf(format,expr-list) 返回格式化字符串。sub(r,s,t) 同gsub,但最多替换一次。sub(r,s) 同gsub,但最多替换一次。substr(s,i,n) 返回字符串s中从第i个字符开始的n个字符。substr(s,i) 返回字符串s中从第i个字符开始的剩余字符。tolower(s) 返回把字符串s转换成小写的结果。toupper(s) 返回把字符串s转换成大写的结果。数学函数——atan2(y,x)cos(x)exp(x)int(x)log(x)rand()sin(x)sqrt(x)srand(expr) srand()
输入输出
12、awk输出使用print或格式化输出printf,printf用法类似于C/C++,输入使用getline,如下例子所示。
$ echo 123 | awk '{print $0}'123$ echo 123 | awk '{printf "%.10d\n", $0}'0000000123
getline每次多读取一行,可以覆盖当前行或者赋值给一个变量,多读取的行将不再被awk处理。
$ cat myfile 1awk12awk223awk3334awk44445awk55555$ awk '{print $0,NF,NR,FNR}' myfile 1awk1 1 1 12awk22 1 2 23awk333 1 3 34awk4444 1 4 45awk55555 1 5 5$ awk '{print $0,NF,NR,FNR,"====="; getline; print $0,NF,NR,FNR,"-----"}' myfile 1awk1 1 1 1 =====2awk22 1 2 2 -----3awk333 1 3 3 =====4awk4444 1 4 4 -----5awk55555 1 5 5 =====5awk55555 1 5 5 -----$ awk '{print $0,NF,NR,FNR,"====="; getline var; print $0,NF,NR,FNR,"-----"}' myfile 1awk1 1 1 1 =====1awk1 1 2 2 -----3awk333 1 3 3 =====3awk333 1 4 4 -----5awk55555 1 5 5 =====5awk55555 1 5 5 -----$ awk '{print $0,NF,NR,FNR,"====="; getline var; print var,NF,NR,FNR,"-----"}' myfile 1awk1 1 1 1 =====2awk22 1 2 2 -----3awk333 1 3 3 =====4awk4444 1 4 4 -----5awk55555 1 5 5 =====4awk4444 1 5 5 -----
自定义函数
13、awk支持自定义函数,一般格式如下:
function name( args ) { statements }
函数中的参数args以逗号分隔,包括输入参数和局部变量,输入参数与局部变量间一般额外地多个空格,可以使用return语句:
return opt_expr
下面例子中的getnumcount函数用于统计每行文本中的数字的个数,使用了内建函数length和substr以及正则匹配,最后打印数字的总个数,结果为9,是正确的。
$ cat myfile 1pear12apple223banana333$ cat myinput BEGIN {count=0}{count+=getnumcount($0)}END {print "total digit count:", count}function getnumcount(s, n, t, i){ n = 0 t = length(s) for(i = 1; i <=t; i++) if(substr(s,i,1) ~ /[0-9]/) n++ return n}$ awk -f myinput myfile total digit count: 9
完结~~
- 【Bash百宝箱】awk
- 【Bash百宝箱】Bash简介
- 【Bash百宝箱】adb
- 【Bash百宝箱】valgrind简介
- 【Bash百宝箱】shell命令
- 【Bash百宝箱】shell函数
- 【Bash百宝箱】shell数组
- 【Bash百宝箱】gcc命令
- 【Bash百宝箱】gdb命令
- 【Bash百宝箱】认识git
- 【Bash百宝箱】xargs
- 【Bash百宝箱】sed
- 【Bash百宝箱】doxygen
- 【Bash百宝箱】Makefile快速入门
- 【Bash百宝箱】Linux shell学习
- 【Bash百宝箱】协作进程coproc
- 【Bash百宝箱】shell重定向
- 【Bash百宝箱】GNU make命令
- linux最基础的命令
- Oracle练习总结一
- 死循环在BEAB BKPT 0xAB汇编的解决办法
- java网络编程精解学习笔记(第二章 socket详解)
- python的sorted函数对字典按key排序和按value排序
- 【Bash百宝箱】awk
- 24.外部化配置
- 初学HTML用法大全指导(二)html对图像的设置
- JAVABEAN EJB POJO区别
- Android和H5互调案例基础详解
- poj A Knight's Journey(DFS)(字典序)
- Java网络编程精解学习笔记(第三章 serverSocket详解)
- mysql 协议的服务端握手包及对其解析
- 手机拨号键盘调试命令