第三章 编程工具awk 什么是awk awk 是一种程序设计语言, 主要用来处 理数据和产生报表. 它对输入数据(文件、标准输入或命令 的输出)逐行进行扫描,匹配指定的模式, 并执行指定的操作。
二. awk的基本格式 1. 语法格式 awk ‘pattern {action}’ filename awk扫描filename中的每一行, 对符合模式 pattern的行执行操作action. 特例: ① awk ‘pattern’ filename 显示所有符合模式pattern的行 ② awk ‘{action}’ filename 对所有行执行操作action
2. 应用实例:(pp. 81) $cat employees Tom Jones 4424 5/12/66 543354 Mary Adams 5436 11/4/63 28765 Sally Chang 1654 7/22/54 650000 Billy Black 1683 9/23/44 336500 $awk ‘/Mary/’ employees Mary Adams 5436 11/4/63 28765 $awk ‘{print $1}’ employees Tom Mary Sally Billy $awk ‘/Sally/ {print $1 $2}’ employees Sally Chang
3. 从其它命令输入 格式: command | awk ‘pattern’ command | awk ‘{action}’ command | awk ‘pattern {action}’ 实例: $who zhanglan tty01 Jan 12 18:36 yuexi tty02 Jan 12 17:03 liuzhen tty15 Jan 12 08:45 $who | awk ‘/tty01/ {print $1}’ (谁在1号终端上) zhanglan
查找包含字符串aaa的行,打印整行内容和这行包含的域数 4. 从标准输入设备(键盘)输入 格式: awk ‘pattern {action}’ 由于未指定输入数据来源, 缺省情况下从标准输入 设备(键盘)读取数据. 键盘上每输入一行, awk就处 理一行, 直到遇到^D为止. 例如: $ awk ‘/aaa/ {print $0, NF}’ bbbb bbbbb bbbbb aaaa aaaaaa aa aaaaaa aaaa aaaaaa aa aaaaaa 4 (awk的输出行) xxx xxxxx yyyyyyy xyz ^D 查找包含字符串aaa的行,打印整行内容和这行包含的域数
三. 格式化输出 print 函数 用于不需要复杂格式的简单输出 例如: $ ps -e | awk ‘/ 05 / {print “tty05: ” $4}’ (查看5号终端上的用户现在在干什么) tty05: sh tty05: cc tty05: find
2. printf 函数 高级格式化输出函数. 用法与C语言中的 用法相同. 实例: uname: Tom ID: 4424 $awk ‘{printf “uname: %-8s ID: %6d\n”, $1, $3}’ employees uname: Tom ID: 4424 uname: Mary ID: 5346 uname: Sally ID: 1654 uname: Billy ID: 1683
四. awk命令文件 格式: awk -f awk_file data_file 当需要对输入数据中的一行执行多项操作时, 常 把这些操作命令放在一个命令文件中, 而不是在命令 行上发出. awk运行时, 对输入数据中的每一行执行命令文件 中的所有操作后, 再对下一行数据进行同样的处理过 程, 依此类推, 直到输入数据的最后一行. ( 要特别注意操作顺序和流程 )
实例: $ cat my_awk /Sally/ {print “**** found Sally! ****”} {print $1, $2, $3} $ awk -f my_awk employees **** found Sally! **** Sally Chang 1654
$0 五. 记录和域 $1 $2 $3 $4 $5 NR=1 Tom Jones 4424 5/12/66 543354 NF=5 五. 记录和域 $1 $2 $3 $4 $5 NR=1 Tom Jones 4424 5/12/66 543354 NF=5 NR=2 Mary Adams 5436 11/4/63 28765 NF=5 NR=3 Sally Chang 1654 7/22/54 650000 NF=5 NR=4 Billy Black 1683 9/23/44 336500 NF=5 $0 $0: 整个记录(整个行) NF: 记录中域的个数 $1: 记录中的第一个域 NR: 输入数据中的记录号 $2: 记录中的第二个域 ….
实例: $ awk ‘/16/ {print NR, $1, $2, $3, NF}’ employees 3 Sally Chang 1654 5 4 Billy Black 1683 5 $ awk ‘/Mary Adams/ {print NR, $0}’ employees 2 Mary Adams 5436 11/4/63 28765 注意: 在查找包含空格的字符串(如Mary Adams)时 要特别小心该空格的状况, 是一个、两个、多个或 Tab符。为避免可能出现的混淆,实际应用中常把 域分隔符设置为可见字符,如分号(;)或冒号(:) 这种方法同时也节省大量的存储空间. ( why? )