Bash 如何使用sed从awk输入变量中搜索和替换html代码字符串

Bash 如何使用sed从awk输入变量中搜索和替换html代码字符串,bash,awk,sed,Bash,Awk,Sed,我有6个文本文件,10列19行。每个文本文件的第一行包含相同的头(awk有意忽略)。出于格式化目的,我将标题创建为表格标题的一部分 示例-foo1.txt(缩短为组成数据的前4行): 包含一些CSS、表位置和要替换的表字符串的模板html文件。不要重写此模板html文件,因为它必须多次用于其他情况(其他6组文本文件)。表字符串(MYTABLE1,MYTABLE2,…)将需要被shell脚本替换 示例-template.html: foo1 我的表1 食物2 我的表2 foo3 我的表3 ba

我有6个文本文件,10列19行。每个文本文件的第一行包含相同的头(awk有意忽略)。出于格式化目的,我将标题创建为表格标题的一部分

示例-foo1.txt(缩短为组成数据的前4行):

包含一些CSS、表位置和要替换的表字符串的模板html文件。不要重写此模板html文件,因为它必须多次用于其他情况(其他6组文本文件)。表字符串(MYTABLE1,MYTABLE2,…)将需要被shell脚本替换

示例-template.html:


foo1
我的表1
食物2
我的表2
foo3
我的表3
bash脚本打开每个文本文件,并使用awk创建行并读取文件以填充标题行下方的每一行。html表包含在来自文本文件的值之间。awk的输出存储为一个变量,然后将该变量传递给sed,以在template.html文件中搜索MYTABLE*字符串,并用包含其他表代码的变量替换它们。然后,sed将创建一个新的html文件,以便不覆盖template.html文件。脚本的awk部分按预期工作,但是sed部分抱怨s/and失败。我想这是因为传递了html代码?我尝试了多种方法让sed接受string变量,每次尝试都有s/failure

示例-make_table.sh(仅包括要创建的前3个表格元素):

#/bin/bash
STRING1=$(cat foo/foo1.txt | awk'NR==1{next}开始{
打印“H1”、“H2”、“H3”、“H4”、“H5”、“H6”、“H7”、“H8”、“H9”、“H10”}
{打印“$1”“$2”“$3”“$4”“$5”“$6”“$7”“$8”“$9”“$10”“”)
STRING2=$(cat foo/foo2.txt | awk'NR==1{next}开始{
打印“H1”、“H2”、“H3”、“H4”、“H5”、“H6”、“H7”、“H8”、“H9”、“H10”}
{打印“$1”“$2”“$3”“$4”“$5”“$6”“$7”“$8”“$9”“$10”“”)
STRING3=$(cat foo/foo3.txt | awk'NR==1{next}开始{
打印“H1”、“H2”、“H3”、“H4”、“H5”、“H6”、“H7”、“H8”、“H9”、“H10”}
{打印“$1”“$2”“$3”“$4”“$5”“$6”“$7”“$8”“$9”“$10”“”)
echo$STRING1
#以上一切都按计划进行
#我试过(运气不好):
#sed-e's/MYTABLE1/'${STRING1}'/'\
#sed-e'c/MYTABLE1/'“$(echo${STRING1})”/”\
#下面的代码不起作用
sed-e's/MYTABLE1/“$(echo${STRING1})”/”\
-e's/MYTABLE2/“$(echo${STRING2})”/”\
-e's/MYTABLE3/“$(echo${STRING3})”/”\
template\u new.html

如何让sed接受那些STRING*命令?这可以在纯awk中完成吗(不确定awk是否可以读取template.html并将输出写入template_new.html)。我真的希望避免使用纯sed解决方案,因为除了简单的字符串替换之外,sed格式没有任何意义。我可以更好地优化awk代码吗?

这是因为字符串包含终止
s
命令的
/
字符。但是,您不必使用
/
字符来分隔
s
命令,
sed
将接受
s
后面的任何内容。尝试使用
#
替代:

sed -e "s#MYTABLE1#${STRING1}#"  \
    -e "s#MYTABLE2#${STRING2}#"  \
    -e "s#MYTABLE3#${STRING3}#"  \
    < template.html > template_new.html
sed-e“s#MYTABLE1#${STRING1}”\
-e“s#MYTABLE2#${STRING2}”\
-e“s#MYTABLE3#${STRING3}”\
template\u new.html
注:我还减少了引用并删除了不需要的
echo
命令


根据POSIX规范,除了反斜杠或换行符之外,您可以使用任何字符作为
s
命令的分隔符。尽管GNU
sed
甚至也会接受反斜杠。请参阅:

如果您在创建模板时知道数据文件的文件名(在您的示例中,它看起来是这样的),那么您可以使用一个awk进程来完成整个工作(而且安全)。假设模板包含类似于
MYTABLE foo1.txt
的行,这些行将被替换为其他保持不变的行,并使用一些变量使代码更短、更清晰:

awk <template >new '
BEGIN{ a="<tr>"; b="<th class=\x22right\x22>"; c="<th>"; d="</th>"; e="</tr>";
  h=a b "H1" d b "H2" d c "H3" d c "H4" d c "H5" d c "H6" d c "H7" d c "H8" d c "H9" d c "H10" d e;
  b="<td class=\x22right\x22>"; c="<td>"; d="</td>" }
$1=="MYTABLE" { f=$2; getline <f; print h; 
  while((getline <f)>0){ print a b $1 d b $2 d c $3 d c $4 d c $4 d c $4 d c $5 d c $6 d c $7 d c $8 d c $9 d c $10 d e };
  close(f); next }
{ print }'

# the close(f) is only required if you have too many files for awk to open concurrently,
# but good practice always
awk新'
开始{a=“”;b=“”;c=“”;d=“”;e=“”;
h=a b“H1”d b“H2”d c“H3”d c“H4”d c“H5”d c“H6”d c“H7”d c“H8”d c“H9”d c“H10”d e;
b=“”;c=“”;d=“”}

$1==“MYTABLE”{f=$2;getline解决方案是使用我所拥有的,并且只将分隔符更改为除正斜杠以外的其他内容。以下方法有效:

sed-e的#MYTABLE1#'“$(echo${STRING1}”#”\
-e's#MYTABLE2#'“$(echo${STRING2}”#”\
-e's#MYTABLE3#'“$(echo${STRING3}”#”\
template\u new.html

不要将
cat
sed
awk
一起使用,他们可以直接读取文件:
STRING3=$(awk'{some awk code}'foo/foo3.txt)
这仍然不能处理我尝试的英镑或其他分隔符字符。它具有相同的“unterminated s”命令错误。@user2030765,你怎么能这样说,然后在下面发布一个答案,说更改分隔符是解决方案?你的答案在命令替换中缺少了右括号
,也许这就是它不起作用的原因。。。?
awk <template >new '
BEGIN{ a="<tr>"; b="<th class=\x22right\x22>"; c="<th>"; d="</th>"; e="</tr>";
  h=a b "H1" d b "H2" d c "H3" d c "H4" d c "H5" d c "H6" d c "H7" d c "H8" d c "H9" d c "H10" d e;
  b="<td class=\x22right\x22>"; c="<td>"; d="</td>" }
$1=="MYTABLE" { f=$2; getline <f; print h; 
  while((getline <f)>0){ print a b $1 d b $2 d c $3 d c $4 d c $4 d c $4 d c $5 d c $6 d c $7 d c $8 d c $9 d c $10 d e };
  close(f); next }
{ print }'

# the close(f) is only required if you have too many files for awk to open concurrently,
# but good practice always