这样可以了解 NR 与 NF 的差别了吧?好了,底下来谈一谈所谓的 "条件类型" 了吧!
既然有需要用到 "条件" 的类别,自然就需要一些逻辑运算啰~例如底下这些:
运算单元 |
代表意义 |
> |
大于 |
< |
小于 |
>= |
大于或等于 |
<= |
小于或等于 |
== |
等于 |
!= |
不等于 |
值得注意的是那个『 == 』的符号,:
- 逻辑运算上面亦即所谓的大于、小于、等于等判断式上面,习惯上是以『 == 』来表示;
- 如果是直接给予一个值,例如变量设定时,就直接使用 = 而已.
好了,我们实际来运用一下逻辑判断吧!举例来说,在 /etc/passwd 当中是以冒号 ":" 来作为字段的分隔, 该档案中第一字段为账号,第三字段则是 UID.那假设我要查阅,第三栏小于 10 以下的数据,并且仅列出账号与第三栏, 那么可以这样做:
[root@www ~]# cat /etc/passwd | \
> awk ''{FS=":"} $3 < 10 {print $1 "\t " $3}''
root:x:0:0:root:/root:/bin/bash
bin 1
daemon 2
....(以下省略).... |
有趣吧!不过,怎么第一行没有正确的显示出来呢?这是我们读入第一行的时候,那些变数 $1, $2... 预设还是以空格键为分隔的,虽然我们定义了 FS=":" 了, 但是却仅能在第二行后才开始生效.那么怎么办呢?我们可以预先设定 awk 的变量啊! 利用 BEGIN 这个关键词喔!这样做:
[root@www ~]# cat /etc/passwd | \
> awk ''BEGIN {FS=":"} $3 < 10 {print $1 "\t " $3}''
root 0
bin 1
daemon 2
......(以下省略)...... |
很有趣吧!而除了 BEGIN 之外,我们还有 END 呢!另外,如果要用 awk 来进行『计算功能』呢?以底下的例子来看, 假设我有一个薪资数据表文件名为 pay.txt ,内容是这样的:
Name 1st 2nd 3th
VBird 23000 24000 25000
DMTsai 21000 20000 23000
Bird2 43000 42000 41000 |
如何帮我计算每个人的总额呢?我还想要格式化输出喔!我们可以这样考虑:
- 第一行只是说明,第一行不要进行加总 (NR==1 时处理);
- 第二行以后就会有加总的情况出现 (NR>=2 以后处理)
[root@www ~]# cat pay.txt | \
> awk ''NR==1{printf "s s s s s\n",$1,$2,$3,$4,"Total" }
NR>=2{total = $2 $3 $4
printf "s d d d .2f\n", $1, $2, $3, $4, total}''
Name 1st 2nd 3th Total
VBird 23000 24000 25000 72000.00
DMTsai 21000 20000 23000 64000.00
Bird2 43000 42000 41000 126000.00 |
上面的例子有几个重要事项应该要先说明的:
- awk 的指令间隔:所有 awk 的动作,亦即在 {} 内的动作,如果有需要多个指令辅助时,可利用分号『;』间隔, 或者直接以 [Enter] 按键来隔开每个指令,例如上面的范例中,鸟哥共按了三次 [enter] 喔!
- 逻辑运算当中,如果是『等于』的情况,则务必使用两个等号『==』!
- 格式化输出时,在 printf 的格式设定当中,务必加上 \n ,才能进行分行!
- 与 bash shell 的变量不同,在 awk 当中,变量可以直接使用,不需加上 $ 符号.
利用 awk 这个玩意儿,就可以帮我们处理很多日常工作了呢!真是好用的很~ 此外, awk 的输出格式当中,常常会以 printf来辅助,, 最好你对 printf 也稍微熟悉一下比较好啦!另外, awk 的动作内 {} 也是支持 if (条件) 的喔! 举例来说,上面的指令可以修订成为这样:
[root@www ~]# cat pay.txt | \
> awk ''{if(NR==1) printf "s s s s s\n",$1,$2,$3,$4,"Total"}
NR>=2{total = $2 $3 $4
printf "s d d d .2f\n", $1, $2, $3, $4, total}'' |
|