关于awk命令的一些知识(第一章)

1 开始使用awk

    awk的GNU实现称为gawk。简单的认为,学习gawk就是学习awk。

# ll /usr/bin/awk
lrwxrwxrwx. 1 root root 4 10月 25 21:08 /usr/bin/awk -> gawk

    当运行awk时,可以指定一个awk程序来告诉awk该怎么做。该程序由一系列规则组成。每个规则指定一个要搜索的模式,并在找到该模式时执行一个动作。从句法上讲,规则由一个模式和一个动作组成。动作用大括号括起来,以将其与模式分开。换行符通常是分开的规则。因此,awk程序如下所示:

pattern { action }
pattern { action }
…

1.1 awk的运行

    有几种方法可以运行awk程序。如果程序很短,则最容易将其包含在运行awk的命令中,如下所示:

awk 'program' input-file1 input-file2 …

    当程序很长时,通常将其放入文件中更为方便,并使用如下命令运行:

awk -f program-file input-file1 input-file2 …
1.1.1 无输入文件运行awk

    示例:

# awk 'BEGIN { print "Don\47t Panic!" }' 
Don't Panic!

    “\47”是一种神奇的方法,可以将一个引号放入程序中,而不必使用丑陋的shell引号技巧:

# awk "BEGIN { print \" Don't Panic! \" }"
 Don't Panic!

    注意,单引号在双引号中不是特殊的。特殊符号有 ` $ \ " 这4个,如果在双引号文本中要将这4个符号按字面意思传递给程序不进行转义,这些字符前面需加反斜杠。
    下一个简单的awk程序模拟cat实用程序,它将您在键盘上键入的内容复制到标准输出:

# awk '{print}'
Now is the time for all good men
Now is the time for all good men
to come to the aid of their country.
to come to the aid of their country.
Four score and seven years ago,...
Four score and seven years ago,...
what,me worry?
what,me worry?
(ctrl+d)
1.1.2 shell引用的问题(单引号与双引号问题)
# awk 'BEGIN { print "Here is a single quote <'"'"'>" }'
Here is a single quote <'>

    混合单引号和双引号是困难的,需要用到这种shell引用技巧。这个程序由三个连在一起的带引号的字符串组成。第一个和第三个是单引号,第二个是双引号。另一种写法如下:

# awk 'BEGIN { print "Here is a single quote <'\''>" }'
Here is a single quote <'>

    另一个选项是使用双引号,转义嵌入的awk级别双引号:

# awk "BEGIN { print \"Here is a single quote <'>\" }"
Here is a single quote <'>

    第三种方法是对单引号和双引号字符使用八进制转义序列等效值:

# awk 'BEGIN { print "Here is a single quote <\47>" }'
Here is a single quote <'>
# awk 'BEGIN { print "Here is a double quote <\42>" }'
Here is a double quote <">

    这方法很好,但是需要清楚转义代表什么。
    第四个方法是使用命令行变量赋值:

# awk -v sq="'" 'BEGIN { print "Here is a single quote <" sq ">" }'
Here is a single quote <'>

    这里,两个字符串常量和sq的值连接成一个字符串,由print打印。
如果真的需要在awk程序中同时使用单引号和双引号,那么最好将它移到一个单独的文件中。

1.2 用于示例的文件

    该文许多示例都是从两个样本文件中获取数据。
    第一个文件名为mail-list:

Amelia       555-5553     amelia.zodiacusque@gmail.com    F
Anthony      555-3412     anthony.asserturo@hotmail.com   A
Becky        555-7685     becky.algebrarum@gmail.com      A
Bill         555-1675     bill.drowning@hotmail.com       A
Broderick    555-0542     broderick.aliquotiens@yahoo.com R
Camilla      555-2912     camilla.infusarum@skynet.be     R
Fabius       555-1234     fabius.undevicesimus@ucb.edu    F
Julie        555-6699     julie.perscrutabor@skeeve.com   F
Martin       555-6480     martin.codicibus@hotmail.com    A
Samuel       555-3430     samuel.lanceolis@shu.edu        A
Jean-Paul    555-2127     jeanpaul.campanorum@nyu.edu     R

    每条记录都包含一个人的姓名、电话号码、电子邮件地址以及与作者的关系代码。列使用空格对齐。最后一栏中的“A”表示此人是熟人。最后一栏中的“F”表示此人是朋友。“R”表示此人是亲属。
    第二个文件名为inventory-shipped,表示一年中发货的信息。每条记录分别包含月份、装运的绿色板条箱数量、装运的红色盒子数量、装运的橙色袋子数量和装运的蓝色包裹数量。共有16个条目,涵盖去年12个月和今年前四个月。一个空行分隔了两年的数据:

Jan  13  25  15 115
Feb  15  32  24 226
Mar  15  24  34 228
Apr  31  52  63 420
May  16  34  29 208
Jun  31  42  75 492
Jul  24  34  67 436
Aug  15  34  47 316
Sep  13  55  37 277
Oct  29  54  68 525
Nov  20  87  82 577
Dec  17  35  61 401

Jan  21  36  64 620
Feb  26  58  80 652
Mar  24  75  70 495
Apr  21  70  74 514

1.3 一些简单示例

    在mail-list中搜索字符串“li”:

# awk '/li/ { print $0 }' mail-list
Amelia       555-5553     amelia.zodiacusque@gmail.com    F
Broderick    555-0542     broderick.aliquotiens@yahoo.com R
Julie        555-6699     julie.perscrutabor@skeeve.com   F
Samuel       555-3430     samuel.lanceolis@shu.edu        A

    在awk规则中,可以省略模式(pattern)或操作(action),但不能同时省略两者。如果省略该模式,则对每个输入行执行该操作。如果省略该操作,则默认操作是打印与模式匹配的所有行。
    因此,可以省略前面示例中的操作(print语句和大括号),结果将是相同的:

# awk '/li/' mail-list             
Amelia       555-5553     amelia.zodiacusque@gmail.com    F
Broderick    555-0542     broderick.aliquotiens@yahoo.com R
Julie        555-6699     julie.perscrutabor@skeeve.com   F
Samuel       555-3430     samuel.lanceolis@shu.edu        A

    一些示例:

  • 打印超过80个字符的每一行
awk 'length($0) > 80' data
  • 打印最长输入行的长度
awk '{ if (length($0) > max) max = length($0) } END { print max }' data
  • 打印数据中最长行的长度
expand data | awk '{ if (x < length($0)) x = length($0) } END { print "maximum line length is " x }'
  • 打印至少有一个字段的每一行
awk 'NF > 0' data

    这是从文件中删除空白行的一种简单方法(或者更确切地说,创建与旧文件相似的新文件,但是已经删除了空白行)。

  • 打印0到100之间的七个随机数
awk 'BEGIN { for (i = 1; i <= 7; i++) print int(101 * rand()) }'
  • 打印files使用的字节总数
ls -l files | awk '{ x += $5 } END { print "total bytes: " x }'
  • 打印所有用户登录名的排序列表
awk -F: '{ print $1 }' /etc/passwd | sort
  • 计算文件中的行数
awk 'END { print NR }' data
  • 打印数据文件中的偶数行
awk 'NR % 2 == 0' data

    如果改用“NR%2==1”表达式,程序将打印奇数行。

参考文档

https://www.gnu.org/software/gawk/manual/gawk.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值