目录

Awk学习

题记

awk是unix下很实用的文本编辑语言。可以快速处理很多操作。参考资料是b站up主正月点灯笼的awk入门教程。这篇博客用来记录一下awk里面非常基础的操作。

待处理的文本

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
gold 1 1986 USA American Eagle
gold 1 1908 Austria-Hungary Franz josef 100 Korona
silver 10 1981 USA ingot
gold 1 1984 Switzerland ingot
gold 1 1979 RSA Krugerrand
gold 0.5 1981 RSA Krugerrand
gold 0.1 1986 PRC Panda
silver 1 1986 USA Liberty dollar
gold 0.25 1986 USA Liberty 5-dollar piece
silver 1 1986 USA Liberty 50-cent piece
silver 1 1987 USA Constitution dollar
gold 0.25 1987 USA Constitution 5-dollar piece
gold 1 1988 Canada Maple leaf

命名为coins.txt, 每一列从左到右分别表示材料、重量、生产时间、生产地、产品名称。

打印内容

  • awk '{print NR "\t" $0 "\t" $5}' coins.txt'

知识点

  1. 行是record,列是field。打印行号用NR
  2. $1表示第一列
  3. $0表示打印全部内容
  4. 注意原本设想的产品名称 列被拆成了多列,比如American Eagle被拆成了2列。
点击展开输出结果 ```awk 1 gold 1 1986 USA American Eagle American 2 gold 1 1908 Austria-Hungary Franz josef 100 Korona Franz 3 silver 10 1981 USA ingot ingot 4 gold 1 1984 Switzerland ingot ingot 5 gold 1 1979 RSA Krugerrand Krugerrand 6 gold 0.5 1981 RSA Krugerrand Krugerrand 7 gold 0.1 1986 PRC Panda Panda 8 silver 1 1986 USA Liberty dollar Liberty 9 gold 0.25 1986 USA Liberty 5-dollar piece Liberty 10 silver 1 1986 USA Liberty 50-cent piece Liberty 11 silver 1 1987 USA Constitution dollar Constitution 12 gold 0.25 1987 USA Constitution 5-dollar piece Constitution 13 gold 1 1988 Canada Maple leaf Maple ```
  • awk '{print NR NR, NR}' coins.txt

知识点:用,逗号来分开,只用空格会被直接忽略掉。

NR NR的打印结果中间没有空格,而NR, NR打印结果是有空格的(注意命令中逗号后面有一个空格)。

点击展开输出结果 ```awk 11 1 22 2 33 3 44 4 55 5 66 6 77 7 88 8 99 9 1010 10 1111 11 1212 12 1313 13 ```

搜索

  • awk '$3==1986{print $0}' coins.txt

打印满足第三列是1986的所有行。

1
2
3
4
5
gold 1 1986 USA American Eagle
gold 0.1 1986 PRC Panda
silver 1 1986 USA Liberty dollar
gold 0.25 1986 USA Liberty 5-dollar piece
silver 1 1986 USA Liberty 50-cent piece
  • awk '$3==1986&&$1=="gold"{print $0}' coins.txt

知识点:对字符串的匹配要加上双引号,否则会被当做变量名

1
2
3
gold 1 1986 USA American Eagle
gold 0.1 1986 PRC Panda
gold 0.25 1986 USA Liberty 5-dollar piece

分割符

为了方便演示,使用Hello,world作为输入。

知识点

  1. awk分割符分为输入分割符和输出分割符
  2. BEGIN 模式:是指 awk 将在读取任何输入行之前立即执行BEGIN 中指定的动作
  3. 和C语言一样,分号;用来分开多个语句
  • echo Hello,world | awk '{print $1, NF}'

    输出:Hello,world 1

  • echo Hello,world | awk 'BEGIN{FS=","} {print $1, $2, NF}'

    输出:Hello world 2

  • echo Hello,world | awk 'BEGIN{FS=","; OFS=","} {print $1, $2, NF}'

    输出:Hello,world,2

变量

  • awk '{$3="xxx"; print FILENAME $0}' coins.txt

知识点

  1. FILENAME可以输出文件名,比如coins.txt.
  2. $3="xxx"把第三列替换了
点击展开输出结果 ```awk coins.txtgold 1 xxx USA American Eagle coins.txtgold 1 xxx Austria-Hungary Franz josef 100 Korona coins.txtsilver 10 xxx USA ingot coins.txtgold 1 xxx Switzerland ingot coins.txtgold 1 xxx RSA Krugerrand coins.txtgold 0.5 xxx RSA Krugerrand coins.txtgold 0.1 xxx PRC Panda coins.txtsilver 1 xxx USA Liberty dollar coins.txtgold 0.25 xxx USA Liberty 5-dollar piece coins.txtsilver 1 xxx USA Liberty 50-cent piece coins.txtsilver 1 xxx USA Constitution dollar coins.txtgold 0.25 xxx USA Constitution 5-dollar piece coins.txtgold 1 xxx Canada Maple leaf ```
  • awk '{print $NF "\t" $(NF-1)}' coins.txt

知识点$NF可以用来打印倒数第某列

点击展开输出结果 ```awk Eagle American Korona 100 ingot USA ingot Switzerland Krugerrand RSA Krugerrand RSA Panda PRC dollar Liberty piece 5-dollar piece 50-cent dollar Constitution piece 5-dollar leaf Maple ```

正则表达式

  • awk '/^g/{print $0}' coins.txt

匹配开头是g的行。

点击展开输出结果 ```awk gold 1 1986 USA American Eagle gold 1 1908 Austria-Hungary Franz josef 100 Korona gold 1 1984 Switzerland ingot gold 1 1979 RSA Krugerrand gold 0.5 1981 RSA Krugerrand gold 0.1 1986 PRC Panda gold 0.25 1986 USA Liberty 5-dollar piece gold 0.25 1987 USA Constitution 5-dollar piece gold 1 1988 Canada Maple leaf ```

正则表达式语法:

  • .匹配任何单字符,要匹配 . ,需使用 \.

    /a.c/ 能够匹配abc, axc等

  • ^$分别表示开始和结尾

  • []表示匹配方括号中的一个字符

    /a[xy]b/能够匹配axb, ayb.

    /a[a-zA-Z]b/能够匹配axb, aXb等.

  • ^在方括号中表示否定

    /a[^a-z]c/能够匹配aAc,但不能匹配aac.

  • *表示可以匹配0次或多次

  • +表示匹配1次或多次

  • ?表示前面的字符可以有也可以没有

    /a?b/可以匹配ab,b。

  • {}用于匹配多个重复字符

    /a{3}c/可匹配aaac。

    /a{1,3}c/可匹配ac,aac,aaac。

    /a{2,}c/可匹配aac,aaaaac等。

  • ()标记一个子表达式的开始和结束位置

    /(ab)+c/可匹配abc, ababababc.