Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

6, awk

850 views

Published on

About linux awk tool

  • Be the first to comment

6, awk

  1. 1. awk
  2. 2. Agenda
  3. 3. 概述• 什么是awk? awk最初是unix上用于处理特定 格式文本的一门编程语言, 后来被移植到 linux. 除了最初的awk版本, 还有nawk在原有 的版本上做了一些改进, gawk则是awk的 GNU实现, 目前linux上使用的是gawk.• awk在很多方面都与sed类似, 如下: 1, 输入: 标准输入, 文本文件, 管道; 2, 语法元素: 正则表达式, 行范围, 命令; 3, 处理方式: 逐行处理.
  4. 4. 如何工作?• 首先介绍一下awk通常处理的文本格式: 文件的每一行都由多个 字段组成, 每个字段之间使用一个或者多个空白字符分开. 类似: Mary 28 IT QA 10000 John 30 IT Development 15000 Mayer 50 IT Manager 30000• awk的工作过程 1, 读取输入的一行(被称为一条记录), 并将这一行赋值给内部变 量$0; 2, 判定当前行是否符合过滤条件(模式, 范围, 条件判断). 如果为 否, 则跳过当前行处理下一行; 3, 根据字段(Field)分隔符(Field Separator)的设置对记录进行分割, 分隔符由变量FS指定默认为空格(包括制表符和空格符). 分割之 后按照字段的顺序依次赋值给内部变量$1, $2, $3......比如第一条 记录的第一个字段是Mary. 4, 执行指定的操作, 比如格式化输出某些字段; 5, 清空内部记录和字段变量($0, $1, $2...), 处理下一行.
  5. 5. 语法格式• awk命令使用如下语法格式: awk ‘condition’ file1 file2... awk ‘action’ file1 file2... awk ‘condition action’ file1 file2... 其中condition表示过滤条件, 只有符合该过滤条件才执行动作. condition可以是: 1), 模式, 比如: /^Mary/; 2), 模式范围, 比如: /^Mary/,/John$/ 3),比较表达式, 比如: $3 > 4000 action表示对当前记录或者某些字段执行的操作, 使用{}进行包 含; 如果没有写action则默认打印该行.• 示例: awk ‘/^Mary/,print $2-’ emp # 打印以Mary开头的记录的 第二个字段 ps -ef | awk ‘/^root /,print $2-‘ # 打印root用户所有进程的pid
  6. 6. 输出 - print函数• awk提供了print函数支持基本的打印功能, 用法如下: 1, 不提供仸何参数, 默认打印当前行$0; 2, 指定参数, 多个参数使用逗号分隔; print会依次打 印这些参数, 每个参数使用变量OFS指定的变量分开, 默认OFS是空格; 如果参数之间不使用逗号分开, 那 么这些参数打印时会连接在一起. print函数中可以使用$0, $1, $2...引用当前的记录或者 字段.• 示例: date | awk {print "Month: " $2 "nYear: ",$6-‘ 输出如下格式: Month: Jan Year: 2013
  7. 7. 输出 - print函数• 转义字符 print函数支持如下常用的转义字符: t 制表符 n 换行 r 回车 b 退格 f 换页 示例: awk /^John/{print "ttHave a nice day, " $1, $2 "!"} emp 输出如下: Have a nice day, John Mayer!
  8. 8. 输出 - 内置变量• 与print函数相关的内置变量有: OFS 输出多个参数时, 指定参数之间的分隔符, 默认为空格. 通过如下方式修改: awk BEGIN,OFS="|"-......’ filename 示例: awk BEGIN{OFS="|"}{print $2,$3, $6} emp OFMT 打印浮点数字时, 指定数字的格式, 示例: # 仅打印小数点后的两位, 作四舍五入 awk BEGIN,OFMT="%.2f"; print 1.24565-‘ 注意: OFS/OFMT变量基本上只有在使用print函数时 才会进行设置, 后面的printf函数无需设置这些变量.
  9. 9. 格式化输出 - printf• printf函数用于格式化输出, 参数由格式控制串和其 他的值表达式组成, 示例: printf(“He is %d years oldn”, 15); 格式控制串: “He is %d years old” 值表达式: 15 printf在打印输出时, 会使用表达式的值代替相应位 置的格式占位符(以%字符开头), 比如这里使用第一 个表达式的值15代替第一个格式占位符%d.• 与print不同的是printf函数不会自动换行, 因此如果 需要换行则需要在格式控制串末尾加上n字符;
  10. 10. 格式化输出 - 格式占位符• printf的格式占位符支持如下类型: c 字符 s 字符串 d 十进制整数 ld 十进制长整数 u 十进制无符号整数 lu 十进制无符号长整数 x 十六进制整数 lx 十六进制长整数 o 八进制整数 lo 八进制长整数 f 浮点数 e 科学计数法表示的浮点数 g 选用e或f中较短的一种形式• 格式占位符可以指定某些修饰符, 比如对齐方式, - 左对齐 # 显示8进制前面加0, 16进制加0x + 使用d,e,f,g转换整数时加上正号+或者负号- 0 指定长度时, 使用0而不是空格进行填充• 示例: echo "linux" | awk {printf "|%-15s|n", $1-‘ # 输出: |linux | awk BEGIN{printf "%.2fn",1.2363-‘ # 输出浮点数, 仅保留两位小数
  11. 11. 过滤条件• awk使用过滤条件来决定是否对当前记录执行操作, 过滤条件分为模式, 模式范围或者比较表达式, 可以使用逻辑操作符&&/||对它们进行组合: 1, 模式 只有匹配某个模式的行才执行给定的操作, 示例: awk ‘/^Mary/,print $2-’ emp # 打印匹配^Mary的行 2, 模式范围 通过指定一个模式范围, 表示仅对该范围内的记录进行操作, 示例: # 打印匹配Mary到匹配John记录的第五个字段 awk /Mary/,/John/{print $5} emp 3,比较表达式 可以通过指定某个比较表达式来决定是否对记录执行操作, 示例: awk ‘$3>=30,print $5-’ emp # 仅当第三个字段>=30执行操作 awk还提供了模式匹配操作符~(匹配)/!~(不匹配), 示例: awk ‘$1 ~ /John/,print-’ emp # 如果第一个字段匹配John则打印• 可以使用逻辑操作符&&/||对这些过滤条件进行组合, 示例: awk ‘/John/ && $3<50 ,print-’ emp # 匹配模式John并且第三个字段 小于50
  12. 12. 比较表达式• awk的比较表达式支持所有的关系运算符, 并提供了 特有的模式匹配运算符, 如下: < 小于 <= 小于或等于 == 等于 != 不等于 >= 大于或等于 > 大于 ~ 匹配模式 !~ 不匹配模式 示例: awk $3==30{print $1,$2} emp awk $6<20000{print $1,$2} emp awk $1 ~ /John/{print $1,$2} emp• 比较表达式可以使用在过滤条件部分, 也可以写在 操作部分, 示例: awk $1 ~ /John/{if($3>25){print $1,$2;}} emp
  13. 13. 范围• 过滤条件可以指定为某个范围, 只有符合该 范围的记录才执行操作. 范围可以由模式指 定, 或者由条件表达式指定, 或者是两者的组 合. 示例: awk ‘NR==1, NR==5’ emp # 打印第一到第五条记录 awk ‘NR==1, /^John/’ emp # 打印第一条记录到匹配 以John开头的记录 awk ‘/^Mary/, /^John/’ emp # 打印匹配以Mary开头的 记录到以John开头的记录
  14. 14. 算数运算• awk支持如下算数运算: + 加 - 减 * 乘 / 除 % 求余 ^ 幂 示例: awk $3*3 > 100{print $1,$2} emp• 算数运算可以使用在条件部分也可以使用在操 作部分, 示例: awk $1 ~ /John/{printf "per year: %dn", $6*12} emp
  15. 15. 逻辑操作符• awk逻辑操作符包括: 逻辑与(&&), 逻辑或 (||), 逻辑非(!). 示例: awk $1 ~ /John/ && $3>20{print $1, $2} emp• 逻辑操作也可以写在操作部分, 示例: awk $1 ~ /John/{if($3>25 && $6>10000)print} emp
  16. 16. 变量• awk允许自定义变量, 变量不需要指定类型, 变量的值可以是字符串或者数字. 如果变量 没有被初始化, 那么会根据情况初始化为空 字符串或者数字0. 变量可以通过下面的方 式定义: 1, 命令行指定 使用-v选项指定一个变量, 示例: awk -v var="abc" BEGIN{print var-‘ 2, 在操作块中定义变量, 示例: awk BEGIN{a=1;print a;}
  17. 17. 变量 - 操作• awk允许对变量作如下赋值操作: = 赋值 示例: a=5,s=“abc” += a+=5 等价于 a=a+5 -= a-=5 等价于 a=a-5 *= a*=5 等价于 a=a*5 /= a/=5 等价于 a=a/5 %= a%=5 等价于 a=a%5 ^= a^=5 等价于 a=a^5• 自增++, 自减-- 对变量进行自增或者自减操作, 示例: awk ‘BEGIN,a=5;a++; print a;-’ # 输出: 6 自增/自减操作符可以放在变量前后, 两者的结果不同. 放在前面 先自增, 然后返回值. 放在后面则先返回值, 后自增. 示例: awk ‘BEGIN,a=5; b=++a;c=a++;print a,b,c;-’ # 输出7 6 6
  18. 18. 内置变量• awk将每读入的一行作为一条记录($0), 每条记录中使用字段分隔符(FS) 分开的字符串作为一个字段($1, $2...). awk有如下内置变量是与它们相 关的: RS 记录分隔符, 默认是n ORS 输出记录分隔符, 默认是n NR 当前的记录号, 从1开始 FNR 记录在当前文件的号码, 每读取一个文件FNR置1 NF 当前记录的字段数 FS 字段分隔符, 默认为空格字符, 通过如下方式修改FS: 1, awk命令的-F选项, 示例: awk -F: # 使用:作为FS awk -F’* :+’ # 使用空格或者:作为FS 2, 使用BEGIN块对FS赋值, 示例: awk ‘BEGIN,FS=":"-......’ OFS 输出字段分隔符, 当使用print打印多个使用逗号分开的参 数时, OFS在每打印一个参数之后被打印. OFS默认为空格. FILENAME 用于处理的文件的名称
  19. 19. 内置变量 NR & FNR• 引用awk文档的解释: NR ordinal number of the current record FNR ordinal number of the current record in the current file NR指的是当前的记录号, 不管出自哪个文件一直递增; FNR指的是在当前文件中的记录号, 每读取一个新的文件 FNR重置为1. 示例: echo "1 abc" > file1 echo "2 def" > file2 awk BEGIN{print "NRtFNRtContent"}{printf "%dt%dt%sn", NR, FNR, $0} file1 file2 输出如下: NR FNR Content 1 1 1 abc 2 1 2 def
  20. 20. BEGIN/END操作块• awk允许在对文件进行操作之前或者操作完成之后 执行指定的动作, 这是通过BEGIN/END操作块来实现 的. 其中BEGIN的操作在处理文件之前发生, END的操 作则在文件处理完成之后发生. 示例: awk BEGIN{print "Begin..."}{print $1}END{print "End..."} emp 首先在打印文件所有记录的第一个字段之前输 出”Begin...”, 完成文件的操作之后打印”End...”• BEGIN块通常用于做一些初始化的工作, 比如定义变 量; END块则常用于做一些总结性的输出. 示例: awk BEGIN{count=0}/^Mary/{count++}END{print "Mary found "count" times"} emp BEGIN块可以独立存在, 即可以没有操作块和输入文 件等. 示例: awk ‘BEGIN,print “Hello AWK”-’ # 打印Hello AWK
  21. 21. 输出重定向• 默认情况下print/printf函数均输出到标准输 出, 可以使用操作符>将输出重定向到指定 的文件. 示例: awk {print $1, $3 > "file"} emp 将第一/三字段重定向到file文件中, 会覆盖 之前已有的内容.• 使用>>对文件进行追加, 与>的区别在于>在 第一次写的时候会清除文件已有内容, 而>> 不会; 之后的写入操作都是追加.
  22. 22. system函数• awk函数system可以用于调用linux系统命令, 该命令可以是shell内置命令也可以是二进制 程序, 示例: awk BEGIN{system("echo Hello AWK")-‘ awk ‘BEGIN,system(“ls -l")-‘• 可以一次调用多个命令, 命令之间使用分号; 分隔, 示例: awk BEGIN{system("echo Hello AWK;echo $?;ls")}
  23. 23. 条件语句• awk支持条件判断语句, 语法格式与c语言相同, 如下: if(...) {...} if(...) {...} else {...} if(...) {...} else if(...) {...} else {...}• 示例: awk ,if($3>=30)print $1, “too high”- emp awk ,if($3>=30),print $1, “too high”- else ,print $1, “normal”-- emp
  24. 24. 循环语句• awk支持如下循环语句: while循环 do...while循环 for循环• 示例: awk {i=1;while(i<=NF){print i, $i;i++}} emp awk {for(i=1;i<=NF;i++){print i, $i}} emp 说明: i=1; $i表示第1个字段 $NF表示最后一个 字段.• 循环控制break/continue 用法与c语言中的break/continue语句相同.
  25. 25. next, exit• next next语句表示完成当前记录的操作, 处理下一 条记录, 示例: # 如果第一个字段匹配Mary开头, 跳过该行处 理下一行 awk {if($1~/^Mary/){next}print NR, $0} emp• exit 退出当前命令, 可以指定一个0-255之间的退出 状态, 0表示成功, 非0失败.示例: awk {if($3 > 45){exit 1}print NR, $0} emp
  26. 26. 数组• awk支持数组数据类型, 但是与普通的数组有所不同. awk的数组是关联 数组, 数组的下表可以是任意的数字和字符串. 与变量一样, 数组不需 要进行声明. 示例: awk {name[x++]=$2};END{for(i=0;i<NR;i++)print i, name[i]} emp 说明: 使用数组记录第二个字段的值. END块用于打印数组的内容.• 因为是关联数组, 不能够向普通的数组一样使用索引进行遍历, awk提 供了如下的方式遍历数组: for(item in array) { print array[item] } 示例: awk /^John/{name[NR]=$1};END{for(i in name)print name[i]} emp 注意: 使用这种方式遍历数组时并不能保证按照数组元素的插入顺序 进行访问.• 使用字符串作为数组下标, 示例: awk ‘,count*$2+++-;END,for(name in count)print name, count*name+-’ emp # 输出 Brown 1 Mayer 3 Black 2
  27. 27. 数组 - split & delete• split函数用于对字符串进行拆分, 并将拆分 后的各项存储在数组中. 示例: awk BEGIN{split("3/15/2004", date, "/");print "The month is " date[1] " and the year is " date[3]} 对字符串”3/15/2004”分解得到数组date.• delete函数用于删除数组的元素, 示例: awk ‘,line*x+++=$2-END,for(x in line)delete line*x+-’ emp
  28. 28. 内置函数 - 字符串函数• awk提供了一些用于文本处理的函数, 列举如下: sub(pattern, replacement) sub(pattern, replacement, target) 示例: # 替换$0中第一个匹配Mary的为Maria awk {sub(/Mary/, "Maria"); print} emp # 替换$1中第一个匹配Mary的为Maria awk ,sub(/Mary/, "Maria“, $1); print- emp gsub(pattern, replacement) gsub(pattern, replacement, target) 与sub不同的是, gsub会进行全局替换 index(string, substring) index函数用于查找子字符串在父串中第一次出现的位置, 不支 持使用正则表达式. 位置从1开始, 如果未出现返回0. 示例: echo "abcdefg" | awk {print index($1, "abc")-’ # 1
  29. 29. 内置函数 - 字符串函数length(string)返回字符串长度, 示例: awk BEGIN{print length("abc")-‘substr(string, start)substr(string, start, size)截取字符串, 如果超出了字符串的长度范围返回实际的字串, 示例: # 返回World awk BEGIN{print substr("Hello World",7,10)-‘match(string, pattern)返回模式在字符串中首次出现的位置, 示例:awk BEGIN{start=match("Good, TED", /[A-Z++$/); print start-‘awk还提供了内部变量RSTART/RLENGHT分别用于保存模式匹配的信息,RSTART表示模式的起始位置, RLENGHT表示模式匹配到字符串的长度.如果没有匹配函数返回值为0, RSTSART设置为0. 示例:awk BEGIN{s="Good, TED";start=match(s, /[A-Z]+$/); if(start>0)printsubstr(s,RSTART,RLENGTH)}
  30. 30. 内置函数 - 字符串函数 split(string, array, separator) split(string, array)split用于将字符串分割为数组, 可以指定分隔符, 若不指定默认内置变量FS为分隔符. 示例: awk BEGIN,split("12/25/2001", date, "/"); print date*2+-‘sprintf(format, expr1, expr2...)与printf相同的是, sprintf用于格式化字符串, 但是它不会将格式化之后的字符串打印到标准输出而是返回. 示例: awk BEGIN{s=sprintf("Name: %-10s Age: %-3d", "Ted","27");print s}
  31. 31. 内置函数 - 算数函数• awk提供了如下算数函数: int(x) 对x进行取整 rand() 返回0-1之间的随机数 srand(x) 设置x为随机数的新种子 sqrt(x) x平方根 sin(x) 正弦函数 cos(x) 余弦函数 log(x) x自然对数(底数e) exp(x) x的e指数函数
  32. 32. 内置函数 - 时间函数• awk提供了如下两个时间函数: 1, systime函数返回自1970/1/1开始经过的时间(按秒计算). 示例: awk BEGIN{print systime();} # 1358479710 2, strftime函数对时间戳进行格式化, 如果不指定时间戳则使用 当前的时间, 语法如下: strftime() 返回按照默认格式的当前时间 strftime(format) 按照指定格式格式化当前时间 strftime(format, timestamp) 按照指定的格式格式化 指定的时间戳 示例: awk BEGIN{print strftime();} # Fri Jan 18 11:33:46 CST 2013 awk BEGIN{print strftime("%D");} # 01/18/13 awk BEGIN{print strftime("%T");} # 11:35:09 awk BEGIN{print strftime("%T", systime());} # 11:36:29
  33. 33. 内置函数 - 时间函数strftime支持的格式说明:%D 采用mm/dd/yy格式表示的日期%T 采用HH/MM/SS格式表示的时间%m 月 %d 日 %y 年, 比如04%Y 年, 比如2004%H 小时24 %I 小时12%M 分钟 %S 秒%b 月Jan %B 月January%a 星期Sun %A 星期Sunday示例: awk BEGIN{print strftime("%Y-%m-%d %H-%M-%S",systime());-‘输出: 2013-01-18 11-45-32
  34. 34. 命令行选项• awk支持如下常用的选项: -v 定义变量, 示例: awk -v var="abc" BEGIN{print var-‘ -F 设置FS的值 -f 执行awk脚本文件 --version打印awk的版本信息
  35. 35. END

×