bash - 如何使用 sed 从 awk 输入变量中搜索和替换 html 代码字符串
问题描述
我有 6 个 10 列和 19 行的文本文件。每个文本文件的第一行包含一个相同的标题(awk 有意忽略)。我创建表头作为表头的一部分以进行格式化。
示例 - foo1.txt(缩短为前 4 行虚构数据):
H1 H2 H3 H4 H5 H6 H7 H8 H9 H10
1 2 3 4 5 6 7 8 9 10
2 3 4 5 6 7 8 9 10 11
3 4 5 6 7 8 9 10 11 12
包含一些 CSS、表格位置和要替换的表格字符串的模板 html 文件。重要的是不要重写此模板 html 文件,因为它必须在其他情况下多次使用(其他 6 个文本文件集)。表字符串(MYTABLE1、MYTABLE2、...)将需要由 shell 脚本替换。
示例 - 模板.html:
<!--some html and css code, followed by below code-->
<div>
<div class="wrap">
<table>
<caption>foo1</caption>
<tbody>
MYTABLE1
</tbody>
</table>
</div>
<div>
<div class="wrap">
<table>
<caption>foo2</caption>
<tbody>
MYTABLE2
</tbody>
</table>
</div>
<div>
<div class="wrap">
<table>
<caption>foo3</caption>
<tbody>
MYTABLE3
</tbody>
</table>
</div>
<!--then, continues through foo6 and MYTABLE6 and other html code-->
bash 脚本打开每个文本文件,并使用 awk 创建行并从文件中读取以填充标题行下方的每一行。表格 html 包含在来自文本文件的值之间。awk 的输出存储为变量,然后将其传递给 sed 以在 template.html 文件中搜索 MYTABLE* 字符串,并用包含附加表代码的变量替换它们。然后,sed就是新建一个html文件,以免覆盖template.html文件。脚本的 awk 部分按预期工作,但是 sed 部分抱怨 's/ 并失败。我想这是因为传递了 html 代码?我尝试了多种方法让 sed 接受字符串变量,每次尝试都有 's/ 失败。
示例 - make_table.sh(仅包括要创建的前 3 个表元素):
#!/bin/bash
STRING1=$(cat foo/foo1.txt | awk ' NR==1{next} BEGIN {
print "<tr><th class=\x22right\x22>H1</th>", "<th class=\x22right\x22>H2</th>", "<th>H3</th>", "<th>H4</th>", "<th>H5</th>", "<th>H6</th>", "<th>H7</th>", "<th>H8</th>", "<th>H9</th>", "<th>H10</th></tr>" }
{ print "<tr><td class=\x22right\x22>" $1 "</td><td class=\x22right\x22>" $2 "</td><td>" $3 "</td><td>" $4 "</td><td>" $5 "</td><td>" $6 "</td><td>" $7 "</td><td>" $8 "</td><td>" $9 "</td><td>" $10 "</td></tr>" }')
STRING2=$(cat foo/foo2.txt | awk ' NR==1{next} BEGIN {
print "<tr><th class=\x22right\x22>H1</th>", "<th class=\x22right\x22>H2</th>", "<th>H3</th>", "<th>H4</th>", "<th>H5</th>", "<th>H6</th>", "<th>H7</th>", "<th>H8</th>", "<th>H9</th>", "<th>H10</th></tr>" }
{ print "<tr><td class=\x22right\x22>" $1 "</td><td class=\x22right\x22>" $2 "</td><td>" $3 "</td><td>" $4 "</td><td>" $5 "</td><td>" $6 "</td><td>" $7 "</td><td>" $8 "</td><td>" $9 "</td><td>" $10 "</td></tr>" }')
STRING3=$(cat foo/foo3.txt | awk ' NR==1{next} BEGIN {
print "<tr><th class=\x22right\x22>H1</th>", "<th class=\x22right\x22>H2</th>", "<th>H3</th>", "<th>H4</th>", "<th>H5</th>", "<th>H6</th>", "<th>H7</th>", "<th>H8</th>", "<th>H9</th>", "<th>H10</th></tr>" }
{ print "<tr><td class=\x22right\x22>" $1 "</td><td class=\x22right\x22>" $2 "</td><td>" $3 "</td><td>" $4 "</td><td>" $5 "</td><td>" $6 "</td><td>" $7 "</td><td>" $8 "</td><td>" $9 "</td><td>" $10 "</td></tr>" }')
echo $STRING1
#everything above works as intended
#I've tried (with no luck):
#sed -e 's/MYTABLE1/'${STRING1}'/' \
#sed -e 'c/MYTABLE1/'"$(echo ${STRING1})"'/' \
#below does not work
sed -e 's/MYTABLE1/'"$(echo ${STRING1})"'/' \
-e 's/MYTABLE2/'"$(echo ${STRING2})"'/' \
-e 's/MYTABLE3/'"$(echo ${STRING3})"'/' \
< template.html > template_new.html
我怎样才能让 sed 接受那些 STRING* 命令?这可以在纯 awk 中完成吗(不确定 awk 是否可以读取 template.html 并将输出写入 template_new.html)。我真的很想避免使用纯 sed 解决方案,因为除了简单的字符串替换之外,sed 格式没有任何意义。我可以更好地优化 awk 代码吗?
解决方案
这是因为您的字符串包含/
终止s
命令的字符。但是,您不必使用/
字符来分隔s
命令,sed
将接受s
. 尝试使用 a#
代替:
sed -e "s#MYTABLE1#${STRING1}#" \
-e "s#MYTABLE2#${STRING2}#" \
-e "s#MYTABLE3#${STRING3}#" \
< template.html > template_new.html
注意我还减少了引用并删除了echo
不需要的命令。
根据 POSIX 规范,您可以使用任何字符作为s
命令的分隔符,而不是反斜杠或换行符。尽管 GNUsed
甚至也会接受反斜杠。请参阅:您可以在 sed 中使用哪些分隔符?
推荐阅读
- jquery - 清除后jquery textarea自动完成不显示
- lua - 如何修复列表错误''}'预计在'附近
' ' 在 Lua 中? - javascript - 如何使用带有 CanvasJS 的 UNIX 时间戳格式化 X 轴日期
- excel - 检查文本是否存在于列的其余部分,如果存在,则使用该行中的信息
- c - 在 C 中计算 csv 和 txt 文件之间的行数问题
- c# - System.Collections.Specialized.NameValueCollection.this[string].get 返回 null
- php - 如何在 WordPress 中进行课程更改?
- node.js - 如何使用nodejs的配置模块从cmd覆盖配置变量值
- python - 无法导入名称“update_contenttypes”
- jmeter - JMeter:如何对批量从数据库表中删除数据进行基准测试?