题记
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'
知识点:
- 行是record,列是field。打印行号用NR
- $1表示第一列
- $0表示打印全部内容
- 注意原本设想的产品名称 列被拆成了多列,比如American Eagle被拆成了2列。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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
打印结果是有空格的(注意命令中逗号后面有一个空格)。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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
作为输入。
知识点:
- awk分割符分为输入分割符和输出分割符
- BEGIN 模式:是指 awk 将在读取任何输入行之前立即执行BEGIN 中指定的动作
- 和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
知识点:
FILENAME
可以输出文件名,比如coins.txt.
$3="xxx"
把第三列替换了
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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
可以用来打印倒数第某列
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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的行。
1
2
3
4
5
6
7
8
9
|
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.