在 shell 脚本中分别提取 2 个相似或不同字符串之间的文本
Extract text between 2 similar or different strings separately in shell script
我想分别提取每个 ###
之间的文本,以便与不同的文件进行比较。需要提取所有 docker 图像的所有 CVE
数字,以便与之前的报告进行比较。文件如下所示。这是一个片段,它有超过 100 行这样的代码。需要通过 Shell 脚本执行此操作。请帮忙。
### Vulnerabilities found in docker image alarm-integrator:22.0.0-150
| CVE | X-ray Severity | Anchore Severity | Trivy Severity | TR |
| :--- | :------------: | :--------------: | :------------: | :--- |
|[CVE-2020-29361](#221fbde4e2e4f3dd920622768262ee64c52d1e1384da790c4ba997ce4383925e)|||Important|
|[CVE-2021-35515](#898e82a9a616cf44385ca288fc73518c0a6a20c5e0aae74ed8cf4db9e36f25ce)|||High|
### Vulnerabilities found in docker image br-agent:22.0.0-154
| CVE | X-ray Severity | Anchore Severity | Trivy Severity | TR |
| :--- | :------------: | :--------------: | :------------: | :--- |
|[CVE-2020-29361](#221fbde4e2e4f3dd920622768262ee64c52d1e1384da790c4ba997ce4383925e)|||Important|
|[CVE-2021-23214](#75eaa96ec256afa7bc6bc3445bab2e7c5a5750678b7cda792e3c690667eacd98)|||Important|
我试过类似的方法grep -oP '(?<=\"##\").*?(?=\"##\")'
,但它不起作用。
预期输出:
For alarm-integrator
CVE-2020-29361
CVE-2021-35515
For br-agent
CVE-2020-29361
CVE-2021-23214
使用您显示的示例,请尝试以下 awk
代码。
awk '
/^##/ && match([=10=],/docker image[[:space:]]+[^:]*/){
split(substr([=10=],RSTART,RLENGTH),arr1)
print "for "arr1[3]
next
}
match([=10=],/^\|\[[^]]*/){
print substr([=10=],RSTART+2,RLENGTH-2)
}
' Input_file
说明: 为以上 awk
代码添加详细说明。
awk ' ##Starting awk program from here.
/^##/ && match([=11=],/docker image[[:space:]]+[^:]*/){ ##Checking condition if line starts from ## AND using match function to match regex docker image[[:space:]]+[^:]* to get needed value.
split(substr([=11=],RSTART,RLENGTH),arr1) ##Splitting matched part in above match function into arr1 array with default delimiter of space here.
print "for "arr1[3] ##Printing string for space arr1 3rd element here
next ##next will skip all further statements from here.
}
match([=11=],/^\|\[[^]]*/){ ##using match function to match starting |[ till first occurrence of ] here.
print substr([=11=],RSTART+2,RLENGTH-2) ##printing matched sub string from above regex.
}
' Input_file ##mentioning Input_file name here.
使用 awk
你可以做到:
awk -v FS=' |[[]|[]]' '/^[#]+/{sub(/:.*$/,"");print "For " $NF} /^\|\[/{print } /^$/ {print ""}' file
For alarm-integrator
CVE-2020-29361
CVE-2021-35515
For br-agent
CVE-2020-29361
CVE-2021-23214
- 我们将字段分隔符
FS
配置为 |[[]|[]]
:space或[
字符或]
字符。
- 第一个条件动作用于获取
For alarm-integrator
和 For br-agent
all CVE numbers
的第二个条件动作
- 最后我们添加空行。
更具可读性:
awk -v FS=' |[[]|[]]' '
/^[#]+/{sub(/:.*$/,"");print "For " $NF}
/^\|\[/{print }
/^$/ {print ""}
' file
For alarm-integrator
CVE-2020-29361
CVE-2021-35515
For br-agent
CVE-2020-29361
CVE-2021-23214
使用 GNU awk(我假设你已经或可以得到,因为你正在使用 GNU grep)为第三个参数匹配():
$ cat tst.awk
match([=10=],/^###.* ([^:]+):.*/,a) { print "For", a[1] }
match([=10=],/\[([^]]+)/,a) { print a[1] }
!NF
$ awk -f tst.awk file
For alarm-integrator
CVE-2020-29361
CVE-2021-35515
For br-agent
CVE-2020-29361
CVE-2021-23214
我想分别提取每个 ###
之间的文本,以便与不同的文件进行比较。需要提取所有 docker 图像的所有 CVE
数字,以便与之前的报告进行比较。文件如下所示。这是一个片段,它有超过 100 行这样的代码。需要通过 Shell 脚本执行此操作。请帮忙。
### Vulnerabilities found in docker image alarm-integrator:22.0.0-150
| CVE | X-ray Severity | Anchore Severity | Trivy Severity | TR |
| :--- | :------------: | :--------------: | :------------: | :--- |
|[CVE-2020-29361](#221fbde4e2e4f3dd920622768262ee64c52d1e1384da790c4ba997ce4383925e)|||Important|
|[CVE-2021-35515](#898e82a9a616cf44385ca288fc73518c0a6a20c5e0aae74ed8cf4db9e36f25ce)|||High|
### Vulnerabilities found in docker image br-agent:22.0.0-154
| CVE | X-ray Severity | Anchore Severity | Trivy Severity | TR |
| :--- | :------------: | :--------------: | :------------: | :--- |
|[CVE-2020-29361](#221fbde4e2e4f3dd920622768262ee64c52d1e1384da790c4ba997ce4383925e)|||Important|
|[CVE-2021-23214](#75eaa96ec256afa7bc6bc3445bab2e7c5a5750678b7cda792e3c690667eacd98)|||Important|
我试过类似的方法grep -oP '(?<=\"##\").*?(?=\"##\")'
,但它不起作用。
预期输出:
For alarm-integrator
CVE-2020-29361
CVE-2021-35515
For br-agent
CVE-2020-29361
CVE-2021-23214
使用您显示的示例,请尝试以下 awk
代码。
awk '
/^##/ && match([=10=],/docker image[[:space:]]+[^:]*/){
split(substr([=10=],RSTART,RLENGTH),arr1)
print "for "arr1[3]
next
}
match([=10=],/^\|\[[^]]*/){
print substr([=10=],RSTART+2,RLENGTH-2)
}
' Input_file
说明: 为以上 awk
代码添加详细说明。
awk ' ##Starting awk program from here.
/^##/ && match([=11=],/docker image[[:space:]]+[^:]*/){ ##Checking condition if line starts from ## AND using match function to match regex docker image[[:space:]]+[^:]* to get needed value.
split(substr([=11=],RSTART,RLENGTH),arr1) ##Splitting matched part in above match function into arr1 array with default delimiter of space here.
print "for "arr1[3] ##Printing string for space arr1 3rd element here
next ##next will skip all further statements from here.
}
match([=11=],/^\|\[[^]]*/){ ##using match function to match starting |[ till first occurrence of ] here.
print substr([=11=],RSTART+2,RLENGTH-2) ##printing matched sub string from above regex.
}
' Input_file ##mentioning Input_file name here.
使用 awk
你可以做到:
awk -v FS=' |[[]|[]]' '/^[#]+/{sub(/:.*$/,"");print "For " $NF} /^\|\[/{print } /^$/ {print ""}' file
For alarm-integrator
CVE-2020-29361
CVE-2021-35515
For br-agent
CVE-2020-29361
CVE-2021-23214
- 我们将字段分隔符
FS
配置为|[[]|[]]
:space或[
字符或]
字符。 - 第一个条件动作用于获取
For alarm-integrator
和For br-agent
all CVE numbers
的第二个条件动作
- 最后我们添加空行。
更具可读性:
awk -v FS=' |[[]|[]]' '
/^[#]+/{sub(/:.*$/,"");print "For " $NF}
/^\|\[/{print }
/^$/ {print ""}
' file
For alarm-integrator
CVE-2020-29361
CVE-2021-35515
For br-agent
CVE-2020-29361
CVE-2021-23214
使用 GNU awk(我假设你已经或可以得到,因为你正在使用 GNU grep)为第三个参数匹配():
$ cat tst.awk
match([=10=],/^###.* ([^:]+):.*/,a) { print "For", a[1] }
match([=10=],/\[([^]]+)/,a) { print a[1] }
!NF
$ awk -f tst.awk file
For alarm-integrator
CVE-2020-29361
CVE-2021-35515
For br-agent
CVE-2020-29361
CVE-2021-23214