如果说sed可以完成行级别文本处理,则awk可以处理文本的每列。
持续扩充中...
目录
如过滤查看docker镜像指定列:仅查看镜像id。
先查看所有镜像,如下:
- docker images
- REPOSITORY TAG IMAGE ID CREATED SIZE
- kindest/node v1.27.3 89e7dc9f9131 2 months ago 932MB
- hello-world latest feb5d9fea6a5 23 months ago 13.3kB
如果只想获得镜像id,则:
docker images| awk '{print $3}'
效果:
- IMAGE
- 89e7dc9f9131
- feb5d9fea6a5
来构造一个多个列的文件:
docker images| awk '{print $2,$3}' > aaa
如上,将镜像列表的第2、3列内容写到了文件aaa中,查看一下:
- #cat aaa
-
- TAG IMAGE
- v1.27.3 89e7dc9f9131
- latest feb5d9fea6a5
查看aaa文件的第2列:
awk '{print $2}' aaa
效果:
- IMAGE
- 89e7dc9f9131
- feb5d9fea6a5
如查看docker镜像列表时,给每个镜像id前后都拼接一个下划线:
docker images| awk '$3 = "_"$3"_"'
效果:
- REPOSITORY TAG _IMAGE_ ID CREATED SIZE
- kindest/node v1.27.3 _89e7dc9f9131_ 2 months ago 932MB
- hello-world latest _feb5d9fea6a5_ 23 months ago 13.3kB
可以看到原地修改$3,拼接_是实现了,可是怎样才能只显示镜像ID这一列?
docker images| awk '{$3 = "_"$3"_";print $3}'
效果:
- _IMAGE_
- _89e7dc9f9131_
- _feb5d9fea6a5_
即 使用print实现。
假设有文件aaa:
- TAG IMAGE
- v1.27.3 89e7dc9f9131
- latest feb5d9fea6a5
输出第3行
awk 'NR==3' aaa
也可以用sed实现:
sed -n 3p aaa
如下,查看文件中包含hello的行:
awk '/hello/' a
或使用sed实现:
sed -n '/hello/p' a
awk '/hello/' a| wc -l
也可以grep实现:
grep -c "hello" a
常见运算符:> < >= <= == != %求余
有文件bbb内容如下:
- #cat bbb
- a b
- 1 1
- 4 4
- 5 6
- 8 7
awk '{if($2>3)print}' bbb
效果:
- a b
- 4 4
- 5 6
awk '{if($2%2==0)print}' bbb
效果:
- a b
- 4 4
- 5 6
awk '{if($1==$2)print}' bbb
效果:
- 1 1
- 4 4
awk '{if($1!=$2 && $1>7)print}' bbb
效果:
- a b
- 8 7
输出文件中第一列值大于等于5的行数
awk '{if($1>=5)print}' bbb| wc -l
效果:
3
替换主要用到gsub函数。格式:gsub(/原内容/, 修改后内容, [ 指定列,不指定则默认所有列 ] )
假设有文件aaa;
- TAG IMAGE
- v1.27.3 89e7dc9f9131
- latest feb5d9fea6a5
接下来我们将第一列中的v字符替换为new:
awk '{gsub(/v/,"new",$1);print $1}' aaa
效果:
- TAG
- new1.27.3
- latest
如果想都看到每列,则将print后的$1去掉即可。
awk '{gsub($1,"new",$1);print}' bbb
效果:
- new b
- new 1
- new 4
- new 6
- new 7
docker images| awk '{$3 = "_"$3"_";print $3}' > aaa
和大多数指令用法一样,使用>完成写入。如果是>> aaa,就是追加而不覆盖。
如下,当前目录有两个文件:
- #ls
- aaa bbb
接下来我们将它们文件名都带一个.txt并打印出来:
ls | awk '{print $0=$0".txt"}'
效果:
- aaa.txt
- bbb.txt
注意,print这里使用$1也可以($2就不行了),但如果前面是用 ll 命令查询,则后面只能用$0得到文件。
此时仅是打印出来看看长什么样,文件名其实没有变。如果要实际更改文件名,则结合使用mv命令通过管道执行:
ls | awk '{print "mv",$0,$0".txt"}' | bash
效果:
- #ls
- aaa.txt bbb.txt
awk 'sub(/^ */, "")' ccc
如果去掉*,则仅去除每行第一个空格。同时注意,此操作不会实际修改文件,仅打印展示。
或:
awk 'sub(/^[ ]*/, "")' ccc
awk 'sub(/^[ -]*/, "")' ccc