题记

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

待处理的文本

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列。

点击展开输出结果

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打印结果是有空格的(注意命令中逗号后面有一个空格)。

点击展开输出结果

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的所有行。

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

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

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"把第三列替换了

点击展开输出结果

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可以用来打印倒数第某列

点击展开输出结果

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