之前说过sed, 今天来说awk, 它也是一个文本处理器。 是linux下的一个命令, 比sed更强大。 搞linux开发, 尤其是后台开发, 这个命令差点儿必需要用到。 awk这三个字母分别代表其三位作者的名字, 而不是某个/某些有意义单词的缩写。

还是那句话,以实践操作为荣, 以仅仅看不练为耻。当然, 理解awk的原理是必须的:读入有'\n'换行符切割的一条记录,将记录按指定的域分隔符划分域,$0表示全部域, $1表示第一个域, $n表示第n个域。 默认域分隔符是空格键或tab键。

鉴于awk涉及的东西太多, 所以本文中, 我们只介绍主要的使用方法, 以后遇到了新的东东。 再加入到本博文中。 滚雪球似地积累。

先来感受一下awk, 我们如果test.txt中的内容:

xxx     Math English C++  Experiment
Monkey 100 90 95 Good
Cat 80 100 60 Perfect
Dog 90 60 70 Great
Tiger 95 85 90 Fantastic

之前。 我们用sed来输出行, 如今, 我们来感受一下用awk输出列, 例如以下:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '{print $2}' test.txt
Math
100
80
90
95 Administrator@51B6904C3C8A485 ~/learn_awk
$

看到了吧, 这就是awk. 注意上面仅仅能是单引號, 不能是双引號, $2表示第二列。

我们来看看awk的一般格式:awk [option]  'pattern {action}' test.txt,  比方上面的awk '{print $2}' test.txt, 此时,採用默认选项。 且条件永远为真。

以下, 我们依据awk的原型来一一说明:

        A.awk 

事实上awk就相当于一个函数名, 没什么好说的了。

        B. option

我们先看例如以下操作。 打印test.txt文件的第二列:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '{print $2}' test.txt
Math
100
80
90
95 Administrator@51B6904C3C8A485 ~/learn_awk

能够看到。 命令中没有选项, 也就是採用了默认选项, 如今如果a.txt中的文件内容为:

xxx|Math|English|C++|Experiment
Monkey|100|90|95|Good
Cat|80|100|60|Perfect
Dog|90|60|70|Great
Tiger|95|85|90|Fantastic

我们再用awk '{print $2}' a.txt就不灵了。 为什么呢? 由于awk '{print $2}' a.txt的选项为空, 默认的是以空格为分隔符, 显然不能进行划分。

那怎么办呢? 此时, 我们应该显式地指明分隔符。 例如以下:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk -F "|" '{print $2}' a.txt
Math
100
80
90
95 Administrator@51B6904C3C8A485 ~/learn_awk
$

这就对了。好了, 兴许我们仍然针对test.txt, 不针对a.txt. 也就是说。 採用默认的选项。

       C. pattern

这个最好理解了。 比方, 条件就是一种模式(但模式不不过条件, 有可能是一些正則表達式等)。我们看到。 在awk '{print $2}' test.txt中。 是无条件的, 所谓无条件即为真。

日本无条件投降。 大概就是这个意思。 当然。 为了讲清楚条件, 我们还是来看看:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '1<2 {print $2}' test.txt
Math
100
80
90
95 Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '1<1 {print $2}' test.txt Administrator@51B6904C3C8A485 ~/learn_awk
$

我们看到。 当条件为真的时候, 才会有真正的打印, 反之, 打个屁。

假设要打印整个文件。 能够这么搞:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '1' test.txt
xxx Math English C++ Experiment
Monkey 100 90 95 Good
Cat 80 100 60 Perfect
Dog 90 60 70 Great
Tiger 95 85 90 Fantastic Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '0' test.txt Administrator@51B6904C3C8A485 ~/learn_awk
$

能够看看到, 条件为真, 有打印。

否则, 没有打印。

       D. action

这个好理解。 无非就是内置命令而已, 比方print $2, 例如以下:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '{print $2}' test.txt
Math
100
80
90
95 Administrator@51B6904C3C8A485 ~/learn_awk
$

当然, 假设你喜欢C/C++语言格式。 那全然能够写成:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '{printf("%s\n", $2)}' test.txt
Math
100
80
90
95 Administrator@51B6904C3C8A485 ~/learn_awk
$

实际上。 在pattern部分, 我们是能够用C/C++语言的if等keyword的, 如:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '{if(1<2) printf("%s\n", $2)}' test.txt
Math
100
80
90
95 Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '{if(1<1) printf("%s\n", $2)}' test.txt Administrator@51B6904C3C8A485 ~/learn_awk
$

我们看到, awk看似非常小, 事实上五脏俱全。

弄清了上面的基本构成, awk就算基本入门了。 既然已经与awk有了初步的恋爱感觉了, 那就要趁热打铁的练习一下。

      一. awk的内置变量

1. $0表示整行, $n表示第n个分段。 例如以下:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '{print $0}' test.txt
xxx Math English C++ Experiment
Monkey 100 90 95 Good
Cat 80 100 60 Perfect
Dog 90 60 70 Great
Tiger 95 85 90 Fantastic Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '{print $2}' test.txt
Math
100
80
90
95 Administrator@51B6904C3C8A485 ~/learn_awk
$

再如:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '{print $1, $3}' test.txt
xxx English
Monkey 90
Cat 100
Dog 60
Tiger 85 Administrator@51B6904C3C8A485 ~/learn_awk
$

2. FILENAME表示文件名。 比方:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '{printf("%s\n", FILENAME)}' test.txt
test.txt
test.txt
test.txt
test.txt
test.txt Administrator@51B6904C3C8A485 ~/learn_awk
$

能够看到, 文件名称被打印出来了。 为什么是5个呢? 由于awk是逐行处理的。

3. NR是当前的行数, 能够理解为number of row, 当然, 假设你非要说now row这种中式英语。 那也能够。

总之。 你要明确。 NR非常实用。例如以下:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '{printf("%d:%s\n", NR, FILENAME)}' test.txt
1:test.txt
2:test.txt
3:test.txt
4:test.txt
5:test.txt Administrator@51B6904C3C8A485 ~/learn_awk
$

那要创建test1.txt---test5.txt怎么搞呢? 也非常easy, 联合我们之前介绍过的xargs, 例如以下:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '{printf("%s%d\n", FILENAME, NR)}' test.txt | xargs touch Administrator@51B6904C3C8A485 ~/learn_awk
$ ls
test.txt test.txt1 test.txt2 test.txt3 test.txt4 test.txt5 Administrator@51B6904C3C8A485 ~/learn_awk
$

4. FNR是文件里的行数。 和NR还是有点小小差别的。 且看:

Administrator@51B6904C3C8A485 ~/learn_awk
$ cp test.txt test_bak.txt Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '{printf("%d:%d:%s\n", NR, FNR, FILENAME)}' test.txt test_bak.txt
1:1:test.txt
2:2:test.txt
3:3:test.txt
4:4:test.txt
5:5:test.txt
6:1:test_bak.txt
7:2:test_bak.txt
8:3:test_bak.txt
9:4:test_bak.txt
10:5:test_bak.txt Administrator@51B6904C3C8A485 ~/learn_awk
$

5. NF表示当前行有多少个段, 学这些东西的时候, 不要死记, 要知道NF是number of field的缩写, 那就清晰了。 例如以下:

Administrator@51B6904C3C8A485 ~/learn_awk
$ echo "good good study" | awk '{print NF}'
3 Administrator@51B6904C3C8A485 ~/learn_awk
$

可见有3个段, 以下我们看看test.txt的每行是不是有5个段:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '{print NF}' test.txt
5
5
5
5
5 Administrator@51B6904C3C8A485 ~/learn_awk
$

果然如此。

6. FS是filed seperator, 也就是段切割符号, 默认情况下为空格, 以下我们不用默认的。 而用"|", 例如以下:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk -F "|" '{print FS}' test.txt
|
|
|
|
| Administrator@51B6904C3C8A485 ~/learn_awk
$

当然, 还有其它的一些内置变量, 在此就不一一举例了, 以后要用的时候, 一查便知。

      二. 常见的一些pattern

1. 条件式的pattern, 我们事实上已经熟悉了。 比方:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '1' test.txt
xxx Math English C++ Experiment
Monkey 100 90 95 Good
Cat 80 100 60 Perfect
Dog 90 60 70 Great
Tiger 95 85 90 Fantastic Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '1<=1' test.txt
xxx Math English C++ Experiment
Monkey 100 90 95 Good
Cat 80 100 60 Perfect
Dog 90 60 70 Great
Tiger 95 85 90 Fantastic Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '1<=0' test.txt Administrator@51B6904C3C8A485 ~/learn_awk
$

2. 来个复杂一点的条件pattern, 例如以下:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk 'length > 30' test.txt
xxx Math English C++ Experiment
Cat 80 100 60 Perfect
Dog 90 60 70 Great
Tiger 95 85 90 Fantastic Administrator@51B6904C3C8A485 ~/learn_awk
$

3. 继续条件pattern, 例如以下:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '$1=="Cat"' test.txt
Cat 80 100 60 Perfect Administrator@51B6904C3C8A485 ~/learn_awk
$

继续加个条件:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '$1!="Cat" && $3>=85' test.txt
xxx Math English C++ Experiment
Monkey 100 90 95 Good
Tiger 95 85 90 Fantastic Administrator@51B6904C3C8A485 ~/learn_awk
$

4. 打印第2-4行:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk 'NR>=2 && NR<=4 {print $0}' test.txt
Monkey 100 90 95 Good
Cat 80 100 60 Perfect
Dog 90 60 70 Great Administrator@51B6904C3C8A485 ~/learn_awk
$

别忘了, 我们的sed也能够, 也蛮牛逼的:

Administrator@51B6904C3C8A485 ~/learn_awk
$ sed -n "2,4"p test.txt
Monkey 100 90 95 Good
Cat 80 100 60 Perfect
Dog 90 60 70 Great Administrator@51B6904C3C8A485 ~/learn_awk
$

好了, 条件式的pattern我们介绍到这里。 以下我们介绍与正則表達式有关的一些pattern.

5. 行过滤, 类似于grep的功能。 如:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '/Cat/' test.txt
Cat 80 100 60 Perfect Administrator@51B6904C3C8A485 ~/learn_awk
$

对了,sed也有类似功能, 例如以下:

Administrator@51B6904C3C8A485 ~/learn_awk
$ sed -n "/Cat/"p test.txt
Cat 80 100 60 Perfect Administrator@51B6904C3C8A485 ~/learn_awk
$

6. 那能不能实现grep -v的功能呢? 肯定能够, 假设你觉得不能, 那太小看awk了, 且看:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '!/Cat/' test.txt
xxx Math English C++ Experiment
Monkey 100 90 95 Good
Dog 90 60 70 Great
Tiger 95 85 90 Fantastic Administrator@51B6904C3C8A485 ~/learn_awk
$

7. 输出以xxxxxx开头的行:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '/^C/' test.txt
Cat 80 100 60 Perfect Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '/^(C|D)/' test.txt
Cat 80 100 60 Perfect
Dog 90 60 70 Great Administrator@51B6904C3C8A485 ~/learn_awk
$

8. 输出以xxxxxx结尾的行:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '/t$/' test.txt
xxx Math English C++ Experiment
Cat 80 100 60 Perfect
Dog 90 60 70 Great Administrator@51B6904C3C8A485 ~/learn_awk
$

9. 自然而言地, 在一个pattern里, 我们能够既有正则又有条件, 如:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '/100/ && $4 >= 60' test.txt
Monkey 100 90 95 Good
Cat 80 100 60 Perfect Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '/100/ && $4 > 60' test.txt
Monkey 100 90 95 Good Administrator@51B6904C3C8A485 ~/learn_awk
$

10. 最后再来一个:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '/^x/, /^D/' test.txt
xxx Math English C++ Experiment
Monkey 100 90 95 Good
Cat 80 100 60 Perfect
Dog 90 60 70 Great Administrator@51B6904C3C8A485 ~/learn_awk
$

当然了。 sed肯定也有此功能。 不信你就翻翻我之前的博文。

       三. 常见的一些action, 实际上主要是内置函数

1. 最常见的print, printf, 例如以下:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '{print $2}' test.txt
Math
100
80
90
95 Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '{printf("%d\n", $2)}' test.txt
0
100
80
90
95 Administrator@51B6904C3C8A485 ~/learn_awk
$

2.  在action中也能够有种逻辑。 比方打印第2-4行:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '{if(NR>=2 && NR<=4) print $0}' test.txt
Monkey 100 90 95 Good
Cat 80 100 60 Perfect
Dog 90 60 70 Great Administrator@51B6904C3C8A485 ~/learn_awk
$

当然, 你也能够把这个if条件移动到pattern中去, 如:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk 'NR>=2 && NR<=4 {print $0}' test.txt
Monkey 100 90 95 Good
Cat 80 100 60 Perfect
Dog 90 60 70 Great Administrator@51B6904C3C8A485 ~/learn_awk
$

3.  计算字符串长度, 相当于C/C++中的length函数

Administrator@51B6904C3C8A485 ~/learn_awk
$ echo "good good study" | awk '{print length}'
15 Administrator@51B6904C3C8A485 ~/learn_awk
$

再如:

Administrator@51B6904C3C8A485 ~/learn_awk
$ awk '{print length}' test.txt
36
30
33
31
35 Administrator@51B6904C3C8A485 ~/learn_awk
$

实际上, awk还有非常多内建的函数。 本文无法覆盖awk的全部内容。 只提供冰山一角的一些东东, 但供入门肯定是没有问题的。兴许会更依据实际, 对本文进行逐渐补充和完好。

肚子饿了。 该吃饭了。

awk基本使用方法简单介绍的更多相关文章

  1. InputStreamReader 和 OutputStreamWriter类使用方法简单介绍,及演示。

    InputStreamReader 和 OutputStreamWriter类使用方法简单介绍. 一.InputStreamReader类 InputStreamReader 将字节流转换为字符流.是 ...

  2. Android Mediaplayer各种属性和方法简单介绍

    主要涉及类:MediaPlayer (1) 当一个MediaPlayer对象被创建或者调用reset()方法之后,它处于空闲状态,调用release()方法后处于结束状态 1,一个MediaPlaye ...

  3. eclipse IDE使用git方法简单介绍

    eclipse下使用git插件上传代码至github 1.eclipse下安装git eclipse  git 插件的安装. 点击 Help->Install New Software-> ...

  4. java类中的static成员变量和static方法简单介绍,持续补充

    一.静态成员变量 1.属于整个类而不是某个对象实例,所以可以直接通过类名和对象名去调用. 2.静态成员属于整个类,当系统第一次使用该类时,就会为其分配内存空间直到该类被卸载才会进行资源回收 二.静态方 ...

  5. python 子进程 subpocess 的使用方法简单介绍

    python的子进程嘛,就是利用python打开一个子进程(当然像是一句废话),但是可能和我们理解的不太一样. 一:如何理解? 我们可能的理解:多开一个进程运行某个python函数(如果只想实现这个功 ...

  6. Python Appium 元素定位方法简单介绍

    Python  Appium  元素定位 常用的八种定位方法(与selenium通用) # id定位 driver.find_element_by_id() # name定位 driver.find_ ...

  7. java 多线程 start方法 run方法 简单介绍。

    一 start开启一个多线程, run 只是一个内部的方法. package com.aaa.threaddemo; /* * start方法的作用? * 在 Java中启动多线程调用的是start方 ...

  8. Java中的wait方法 简单介绍。

    一 wait方法怎么用? package com.aaa.threaddemo; /* * 多线程中的wait方法? public final void wait() throws Interrupt ...

  9. CFileDialog的使用方法简单介绍

    CFileDialog文件选择对话框的使用:首先构造一个对象并提供对应的參数,构造函数原型例如以下: CFileDialog::CFileDialog( BOOL bOpenFileDialog, L ...

随机推荐

  1. js模块化入门与commonjs解析与应用

    JS模块化的基本原理 commonjs规范 commonjs在前端模块化中的基本使用 AMD与CMD规范剖析博客链接 一.JS模块化基本原理 在JS没有提出来模块化的时候,开发JS项目比较简单,同时也 ...

  2. Java开发中常见的异常问题

    要调试程序,自然需要对程序中的常见的异常有一定的了解,因此在这里我将一些常见的Java程序中的异常列举出来给大家参考 AD: 作为一名开发者,Java程序员,很自然必须熟悉对程序的调试方法.而要调试程 ...

  3. jdk环境变量配置至第一个简单程序运行成功

    桌面右键单击我的电脑,属性,高级,环境变量,然后再系统变量中配置(也可在用户变量中配置) 在配置环境变量时限查看是否已存在变量名称,有则添加路径,没有则创建再添加路径 /* JAVA_HOME% C: ...

  4. Go:channel

    一.channel 在 Go 语言里,不仅可以使用原子函数和互斥锁来保证对共享资源的安全访问以及消除竞争状态,还可以使用 channel,通过发送和接收需要共享的资源,在 goroutine 之间做同 ...

  5. Linux I2C驱动

    Linux I2C 驱动结构 i2c体系结构由三部分组成 i2C core i2c core提供了i2c 总线驱动 和 设备驱动的注册,注销方法 i2C and SMBus protocol 实现 i ...

  6. Java:获取文件内容

    文章来源:https://www.cnblogs.com/hello-tl/p/9139353.html import java.io.*; public class FileBasicOperati ...

  7. Python-接口自动化(十一)

    配置文件的作用(十一) (十二)配置文件 1.python当中有一个模块可以读取配置文件里面的信息:configparser,对这个模块进行导入之后就可以使用了,import configparser ...

  8. 杭电 4907 Task schedule ·

    Description 有一台机器,并且给你这台机器的工作表,工作表上有n个任务,机器在ti时间执行第i个任务,1秒即可完成1个任务. 有m个询问,每个询问有一个数字q,表示如果在q时间有一个工作表之 ...

  9. 小白菜OJ 1122 公牛母牛配(最大二分图匹配模板)

    题意: n只公牛和m只母牛,某些公牛和某些母牛互相喜欢.但最后一只公牛只能和一只母牛建立一对一匹配.要使得最后牛群匹配对数最大. 链接: http://caioj.cn/problem.php?id= ...

  10. POJ 3310 Caterpillar(图的度的判定)

    题意: 给定一幅图, 问符不符合一下两个条件: (1) 图中没有环 (2)图中存在一条链, 点要么在链上, 要么是链上点的邻居. 分析: 建图,记录度数, 去掉所有度为1的点, 然后看看剩下是否是有2 ...