awk输出函数printf
目前为 止,所有例子的输出都是直接到屏幕,除了t a b键 以外没有任何格式。a w k提 供函数p r i n t f,拥有几种不同的格式化输出功能。例如按列输出、左对齐或右对齐方式。
每一种p r i n t f函数(格式控制字符)都以一个%符号开始,以一个决定转换的字符结束.转换包含三种修饰符。
p r i n t f
函数基本语法是p r i n t f[格式控制符],参数),格式控制字符通常在引号 里。

printf
修饰符

[Copy to clipboard] [ - ]

CODE:

- 左对齐
Wi d t h
域的步长,用0表示0步长
. p r e c
最大字符串长度,或小数点右边的位数
9-7 awk printf格式
% c A S C I I
字符
% d
整 数
% e
浮 点数,科学记数法
% f
浮 点数,例如(1 2 3 . 4 4
% g a w k
决定使用哪种浮点数转换e或者f
% o
八 进制数
% s
字 符串
% x
十 六进制数

 


1. 字符转换
观察A S C I I码中6 5的等价值。管道输出6 5a w kp r i n t f进行A S C I I码字符转换。这里也加入换行,因为缺省情况下p r i n t f不做换行动作。

[Copy to clipboard] [ - ]

CODE:

A[sam@chenwy sam]$ echo "65" | awk '{printf "%c\n",$0}'
A


按同样 方式使用a w k得到同样结果。

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ awk 'BEGIN{printf "%c\n",65}'
A


所有的 字符转换都是一样的,下面的例子表示进行浮点数转换后‘ 9 9 9’的输出结果。整数传入后被加了六 个小数点。

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ awk 'BEGIN{printf "%f\n",999}'
999.000000


2.
格式化输出
打印所 有的学生名字和序列号,要求名字左对齐, 1 5个 字符长度,后跟序列号。注意\ n换行符放在最后一个指示符后面。输出将自动分成两列。

[Copy to clipboard] [ - ]

CODE:

[root@chenwy sam]# awk '{printf "%-15s %s\n",$1,$3}' grade.txt
M.Tans          48311
J.Lulu          48317
P.Bunny         48
J.Troll         4842
L.Tansl         4712


加入一 些文本注释帮助理解报文含义。可在正文前嵌入头信息。注意这里使用p r i n t加入头信息。如果愿意,也可使用p r i n t f

[Copy to clipboard] [ - ]

CODE:

[root@chenwy sam]# awk 'BEGIN{print "Name\t\tS.Number"}{printf "%-15s %s\n",$1,$3}' grade.txt
Name            S.Number
M.Tans          48311
J.Lulu          48317
P.Bunny         48
J.Troll         4842
L.Tansl         4712


3.
向一行a w k命令传值
在查看a w k脚本前,先来查看怎样在a w k命令行中传递变量。
a w k执行前将值传入a w k变量,需要将变量放在命令行中,格式如下:

[Copy to clipboard] [ - ]

CODE:

awk 命令变量=输入文件值


(后面 会讲到怎样传递变量到a w k脚本中)。
下面的 例子在命令行中设置变量A G E等于1 0,然后传入a w k中,查询年龄在1 0岁以下的所有学生。

[Copy to clipboard] [ - ]

CODE:

[root@chenwy sam]# awk '{if ($5<AGE) print $0}' AGE=10 grade.txt
M.Tans 5/99 48311 Green 8 40 44
J.Lulu 06/99 48317 green 9 24 26


要快速 查看文件系统空间容量,观察其是否达到一定水平,可使用下面a w k一行脚本。因为要监视的已使用空间 容量不断在变化,可以在命令行指定一个触发值。首先用管道命令将df -k 传入a w k,然后抽出第4列,即剩余可利用空间容量。使用$ 4 ~ / ^ [ 0 - 9 ] /取得容量数值(1 0 2 4块)而不是d f的文件头,然后对命令行与‘ i f ( $ 4 < T R I G G E R )’上变量T R I G G E R中指定
的值进 行查询测试。

[Copy to clipboard] [ - ]

CODE:

[root@chenwy sam]# df -k|awk '{if($4<TRIGGER) print $6"\t"$4}' TRIGGER=560000
/boot   458589
/dev/shm        99352



[Copy to clipboard] [ - ]

CODE:

[root@chenwy sam]# df -k|awk '($4~/^[0-9]/) {if($4<TRIGGER) print $6"\t"$4}' TRIGGER=5600000
/       2610716
/boot   458589
/dev/shm        99352


($4~/^[0-9]/)好像没什么用

在系统 中使用df -k命令,产生下列信息:

[Copy to clipboard] [ - ]

CODE:

[root@chenwy sam]# df -k
文件系 统               1K-        已用     可 用 已用% 挂载点
/dev/sda2              5162828   2289804   2610764  47% /
/dev/sda1               497829     13538    458589   3% /boot
none                     99352         0     99352   0% /dev/shm


如果系 统中d f输出格式不同,必须相应改变列号以适应工作系统。
当然可 以使用管道将值传入a w k。本例使用w h o命令, w h o命令第一列包含注册用户名,这里打印注册用户,并加入一定信息。

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ who |awk '{print $1" is logged on"}'
root is logged on
root is logged on
[sam@chenwy sam]$ who
root     :0           Nov 23 20:17
root     pts/0        Nov 23 20:25 (:0.0)


a w k
也允许传入环境变量。下面的例子使用环境变量HOME支持当前用户目录。可从pwd命令管道输出到a w k中获得相应信息。

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ pwd | awk '{if ($1==derr) print $1}' derr=$HOME
/usr/sam


4. awk
脚本文件
可以将a w k脚本写入一个文件再执行它。命令不必很长(尽管这是写入一个脚本文件的主要原因),甚至可以接受一行命令。这样可以保存a w k命令,以使不必每次使用时都需要重新输入。使用文件的另一个好处是可以增加注释,以便于理解脚本的真正用途和功能。
使用前 面的几个例子,将之转换成a w k可执行文件。像原来做的一样,将学生目前级别分相加awk ‘t o t + = $ 6 END{print "club student total points" t o t }’ g r a d e . t x t
创建新 文件s t u d e n t _ t o t . a w k,给所有a w k程 序加入a w k扩 展名是一种好习惯,这样通过查看文件名就知道这是一个a w k程序。文本如下:

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ cat student_tot.awk
#!/bin/awk -f
#all commnet lines must start with a hash '#'
#name:students_tots.awk
#to call:student_tot.awk grade.txt
#prints total and average of club student points

#print a header first
BEGIN{
print "Student  Date  Member  No.  Grade Age  Points Max"
print "Name     Joined                        Gained  Point Available"
print "=============================================================="
}
#let's add the scores of points gained
(tot+=$6)

#finished proessing now let's print the total and average point
END{
print "Club student total points :" tot
print "Average Club Student Points:" tot/NR}


通过将 命令分开,脚本可读性提高,还可以在命令之间加入注释。这里加入头
信息和 结尾的平均值。基本上这是一个一行脚本文件。
执行 时,在脚本文件后键入输入文件名,但是首先要对脚本文件加入可执行权限。

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ chmod u+x student_tot.awk
[sam@chenwy sam]$./student_tot.awk grade.txt
Student  Date  Member  No.  Grade Age  Points Max
Name     Joined                        Gained  Point Available
==============================================================
M.Tans 5/99 48311 Green 8 40 44
J.Lulu 06/99 48317 green 9 24 26
P.Bunny 02/99 48 Yellow 12 35 28
J.Troll 07/99 4842 Brown-3 12 26 26
L.Tansl 05/99 4712 Brown-2 12 30 28
Club student total points :155
Average Club Student Points:31


过 滤相同行:
如有一 个文件strip中有多条重复错误提法:

[Copy to clipboard] [ - ]

CODE:

[sam@Linux_chenwy sam]$ cat strip
etreiytrpytyu
ERROR*
ERROR*
ERROR*
ERROR*
IUEWROPYJRTMELUYK
ERROR*
ERROR*
ERROR*
ERROR*
ERROR*
ERROR*
EWUTIRWJYHT
ERROR*
ERROR*
JGIOERYO56ERU
ERROR*
ERROR*
ERROR*
JGEORYKP65EKU;YK,


现在用a w k脚本过滤出错误行的出现频率,使得每一个失败记录只对应一个错误行。awk脚本如下:

[Copy to clipboard] [ - ]

CODE:

[sam@Linux_chenwy sam]$ cat error_strip.awk
#!/bin/awk -f
#error_strip.awk
#to call:error_strip.awk<filename>
#strips out the ERROR* lines if there are more than one
#ERROR* lines after each failed record.

BEGIN {error_line=""}
#tell awk the whole is "ERROR*"
{if ($0=="ERROR*" && error_line=="ERROR*")

#go to next line
next;
error_line=$0;print}


执行结 果如下:

[Copy to clipboard] [ - ]

CODE:

[sam@Linux_chenwy sam]$ ./error_strip.awk strip
etreiytrpytyu
ERROR*
IUEWROPYJRTMELUYK
ERROR*
EWUTIRWJYHT
ERROR*
JGIOERYO56ERU
ERROR*
JGEORYKP65EKU;YK,