在linux中,下面的命令
terraform providers
输出结果如下
.
├── provider[xxx.com/edu/xxxvenafi] 1.2.0
├── provider[registry.terraform.io/hashicorp/kubernetes] 2.3.2
├── provider[xxx.com/edu/xxxsmaas] 1.0.1
├── provider[registry.terraform.io/hashicorp/aws]
├── module.standard_deployment
│ ├── provider[xxx.com/edu/xxxsmaas] 1.0.1
│ ├── provider[xxx.com/edu/xxxvenafi] 1.2.0
│ ├── provider[registry.terraform.io/hashicorp/kubernetes]
│ └── provider[registry.terraform.io/hashicorp/local]
└── module.standand_ingress
├── provider[registry.terraform.io/hashicorp/kubernetes]
├── provider[xxx.com/edu/xxxsmaas] 1.0.1
├── provider[xxx.com/edu/xxxvenafi] 1.2.0
└── provider[registry.terraform.io/hashicorp/aws]
Providers required by state:
provider[xxx.com/edu/xxxsmaas]
provider[xxx.com/edu/xxxvenafi]
provider[registry.terraform.io/hashicorp/aws]
provider[registry.terraform.io/hashicorp/kubernetes]
从输出中删除这些树结构的最佳方法是什么?最终目标是只列出唯一的行,如下所示
provider[xxx.com/edu/xxxvenafi] 1.2.0
provider[xxx.com/edu/xxxsmaas] 1.0.1
$ awk '/[0-9]$/ && sub(/[^[:alpha:]]+/,"") && !seen[$0]++' file
provider[xxx.com/edu/xxxvenafi] 1.2.0
provider[registry.terraform.io/hashicorp/kubernetes] 2.3.2
provider[xxx.com/edu/xxxsmaas] 1.0.1
或者如果你真的只希望行以1.0.1或1.2.0结尾,就像你在评论中说的:
$ awk '/ 1.((0.1)|(2.0))$/ && sub(/[^[:alpha:]]+/,"") && !seen[$0]++' file
provider[xxx.com/edu/xxxvenafi] 1.2.0
provider[xxx.com/edu/xxxsmaas] 1.0.1
使用sed
和sort
,您可以尝试以下操作
$ sed -E 's/.*(provider.*)/1/g;/^[a-z]/!d' input_file | sort -u
provider[registry.terraform.io/hashicorp/aws]
provider[registry.terraform.io/hashicorp/kubernetes]
provider[registry.terraform.io/hashicorp/kubernetes] 2.3.2
provider[registry.terraform.io/hashicorp/local]
provider[xxx.com/edu/xxxsmaas] 1.0.1
provider[xxx.com/edu/xxxvenafi] 1.2.0
这可能不是最有效的。
编辑
摘自Hai Vu的评论,这里有一个适用于op的grep替代方案。
terraform providers | grep -o 'provider.*[0-9][^]]*$' | sort -u
With awk:
terrraform providers |
awk 'BEGIN {FS="provider"}
/xxx.com/ && NF==2 {printf("%s%sn", FS, $2)}' |
sort -u
或避免调用sort
:
terrraform providers |
awk 'BEGIN {FS="provider"}
/xxx.com/ && NF==2 {a[$2]}
END {
for (key in a) {
printf("provider%sn", key)
}
}'
这可能适合您(GNU sed):
sed -nE 's/.*(provider)/1/;ta;$!d;bb;:a;H;g
s/((nS+]).*)2[^n]*$/1/;h;$!d;:b;x;s/.//p' file
关闭隐式打印-n
,打开扩展regexp-E
。
匹配包含provider
的行,删除任何序言并跳转到:a
。
如果没有找到匹配,并且不是最后一行,则删除它并重复。
如果没有找到匹配并且是最后一行,则跳转到:b
。
在:a
处,将当前行附加到保持空间,然后将保持空间复制到当前行。
使用模式匹配,将以前的线路键与当前线路键进行比较,如果已经添加了该键,则删除当前线路。
将结果复制到保持空间,如果不是最后一行,则删除并重复。
在文件末尾:b
,交换到保持空间,删除开始处引入的换行符并打印结果。