?如果说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