bash - 如何用awk替换变量输出字符串?
问题描述
我有一个将 yaml 转换为 html 表的 awk 脚本,其工作原理如下。
YAML 文件内容:
- soft1:
V1.0.1: http://example.com/v1.0.1.zip
V1.0.2: http://example.com/v1.0.2.zip
V1.0.3: http://example.com/v1.0.3.zip
- soft1_beta_ver:
V1.0.1: http://example.com/v1.0.1.zip
V1.0.2: http://example.com/v1.0.2.zip
V1.0.3: http://example.com/v1.0.3.zip
- soft1_alpha_ver:
V1.0.1: http://example.com/v1.0.1.zip
V1.0.2: http://example.com/v1.0.2.zip
V1.0.3: http://example.com/v1.0.3.zip
- soft2:
V1.0.1: http://example.com/v1.0.1.zip
V1.0.2: http://example.com/v1.0.2.zip
V1.0.3: http://example.com/v1.0.3.zip
- soft2_beta_ver:
V1.0.1: http://example.com/v1.0.1.zip
V1.0.2: http://example.com/v1.0.2.zip
V1.0.3: http://example.com/v1.0.3.zip
- soft2_alpha_ver:
V1.0.1: http://example.com/v1.0.1.zip
V1.0.2: http://example.com/v1.0.2.zip
V1.0.3: http://example.com/v1.0.3.zip
< Omit more... >
AWK脚本内容:
#!/usr/bin/env awk
/^-/ {
sub(/:$/,"")
out = type = $NF
sub(/_.*/,"",out)
close(out)
if ( !seen[out]++ ) {
prtBeg()
}
next
}
{
sub(/:$/,"",$1)
prtElt("<tr>")
prtElt("<td>" type "</td>")
prtElt("<td>" $1 "</td>")
prtElt("<td>" $2 "</td>")
prtElt("</tr>")
}
END {
for (out in seen) {
prtEnd()
}
}
function prtElt(str) {
depth[out] += gsub("<[^/<>]+>","&",str)
printf "%*s%s\n", (depth[out]-1)*4, "", str > out".html"
depth[out] -= gsub("</[^<>]+>","&",str)
}
function prtBeg() {
prtElt("<table>")
prtElt("<thead>")
prtElt("<tr>")
prtElt("<th>type</th>")
prtElt("<th>ver</th>")
prtElt("<th>link</th>")
prtElt("</tr>")
prtElt("</thead>")
prtElt("<tbody>")
}
function prtEnd() {
prtElt("</tbody>")
prtElt("</table>")
}
通过使用该cat xxx.yml | awk -f xxx.awk
命令,它会分别输出到多个文件中,内容是这样的。
[root@localhost html]# ls
soft1.html soft2.html test.awk test.yml
[root@localhost html]# cat soft1.html
<table>
<thead>
<tr>
<th>type</th>
<th>ver</th>
<th>link</th>
</tr>
</thead>
<tbody>
<tr>
<td>soft1</td>
<td>V1.0.1</td>
<td>http://example.com/v1.0.1.zip</td>
</tr>
<tr>
<td>soft1</td>
<td>V1.0.2</td>
<td>http://example.com/v1.0.2.zip</td>
</tr>
<tr>
<td>soft1</td>
<td>V1.0.3</td>
<td>http://example.com/v1.0.3.zip</td>
</tr>
<tr>
<td>soft1_beta_ver</td>
<td>V1.0.1</td>
<td>http://example.com/v1.0.1.zip</td>
</tr>
<tr>
<td>soft1_beta_ver</td>
<td>V1.0.2</td>
<td>http://example.com/v1.0.2.zip</td>
</tr>
<tr>
<td>soft1_beta_ver</td>
<td>V1.0.3</td>
<td>http://example.com/v1.0.3.zip</td>
</tr>
<tr>
<td>soft1_alpha_ver</td>
<td>V1.0.1</td>
<td>http://example.com/v1.0.1.zip</td>
</tr>
<tr>
<td>soft1_alpha_ver</td>
<td>V1.0.2</td>
<td>http://example.com/v1.0.2.zip</td>
</tr>
<tr>
<td>soft1_alpha_ver</td>
<td>V1.0.3</td>
<td>http://example.com/v1.0.3.zip</td>
</tr>
</tbody>
</table>
我想type
用自定义字符串替换表格中的“”字符串,比如soft1
替换为Release version
、soft1_beta_ver
替换为Beta version
、soft1_alpha_ver
替换为Alpha version
。
我怎样才能做到这一点?任何帮助提前谢谢你!
解决方案
在顶部添加:
BEGIN {
map["soft1"] = "Release version"
map["soft1_beta_ver"] = "Beta version"
map["soft1_alpha_ver"] = "Alpha version"
}
并更改以下两行:
out = type = $NF
sub(/_.*/,"",out)
至:
out = type = $NF
if (type in map) {
type = map[type]
}
sub(/_.*/,"",out)
如果您要进行更多的文本操作,请阅读 Arnold Robbins 的《Effective Awk Programming, 4th Edition》一书,了解如何使用 awk。
推荐阅读
- firebase - Flutter firebase 触发邮件实现
- json - 使用 Python 读取 JSON 文件 - JSONDecodeError 额外数据
- c++ - 如果我在单独的文件中定义它,g++ 无法链接我的类函数
- python - 将大量 DataFrame 的多列与复杂的重复行进行比较
- python - 如何更改条形图 x 轴上的值?
- docker - 推送 docker 映像期间的 Github 操作错误
- ios - SwiftUI - 如何为 VoiceOver 添加属性可访问性标签,以控制口语音调?
- ruby-on-rails - 如何使用设计邀请重新向用户发送邀请?
- android - 如何恢复 Android webview 透明度设置?
- android - AWS S3 同步存储桶向文件名添加随机扩展名