我有10列19行的6个文本文件。 每个文本文件的第一行包含一个相同的头(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

模板html文件,其中包含一些CSS,表位置和要替换的表字符串。 请勿覆盖此模板html文件,这一点很重要,因为在其他情况下(其他6个文本文件集)必须多次使用它。 表字符串(MYTABLE1,MYTABLE2等)将是需要用shell脚本替换的字符串。

示例-template.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

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

#1楼 票数:2

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

sed -e "s#MYTABLE1#${STRING1}#"  \
    -e "s#MYTABLE2#${STRING2}#"  \
    -e "s#MYTABLE3#${STRING3}#"  \
    < template.html > template_new.html

注意我也减少了引用并删除了不需要的echo命令。

根据POSIX规范,除反斜杠或换行符外,您可以将任何字符用作s命令的定界符。 尽管GNU sed甚至也接受反斜杠。 请参阅: 您可以在sed中使用哪些定界符?

#2楼 票数:0

如果您在创建模板时知道数据文件的文件名(在您的示例中看起来像您一样),则可以通过一个awk进程 (安全地) 完成整个工作 假设模板包含MYTABLE foo1.txt类的行, 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

还要注意,可以使用-f而不是在命令行中将awk的脚本放在文件中,但是两种方法的功能都是相同的。

#3楼 票数:0 已采纳

解决方案是使用我拥有的内容,仅将定界符更改为除正斜杠之外的其他内容。 以下作品:

sed -e 's#MYTABLE1#'"$(echo ${STRING1}"'#'  \
    -e 's#MYTABLE2#'"$(echo ${STRING2}"'#'  \
    -e 's#MYTABLE3#'"$(echo ${STRING3}"'#'  \
    < template.html > template_new.html

  ask by user2030765 translate from so

未解决问题?本站智能推荐:

4回复

使用awk或sed替换字符串中的字符

给定下面的字符串,我如何通过使用awk或sed获取第14和15位数字来替换第6和第7位。 输出 我是新手,对不起我的问题。
2回复

如何使用sed或awk替换csv文件中的字符串

抱歉,这是一个非常基本的问题 如何用一些字符串替换csv文件中的特定列? 例如 我想将第2列和第3列中的任何字符串替换为true,其他字符串将为false,但不是1,2行和结束行。 输出: 我尝试的是以下示例代码(仅尝试在第3列中将字符串替换为“true”):
3回复

使用awk或sed在文件中动态替换字符串

我需要将文件中的文件名替换为cp命令的字符串,因此它应该用同一文件中的cp源目标替换现有文件名。文件是逗号分隔的#m示例文件 现在我想要一个sed或awk命令,它可以将/ /apps/home/<filename>.txt cp /apps/home/<filename
4回复

如何在 sed 和 awk(和 perl)中搜索和替换任意文字字符串

假设我们在文件中有一些任意文字,我们需要用其他文字替换它们。 通常,我们只需使用sed (1) 或awk (1) 并编写如下代码: 但是,如果 $target 和/或 $replacement 可能包含对sed (1) 敏感的字符,例如正则表达式,该怎么办。 你可以逃避它们,但假设你不知道它们
35回复

如何使用 awk 或 sed 递归查找/替换字符串?

我如何查找和替换每次出现的: 和 在/home/www/目录树下的每个文本文件中递归?
3回复

使用基于 sed/awk 的 linux 替换字符串

我想更换这个 有了这个 我尝试了两种方法 方法一 方法二 但他们两个都不起作用。
1回复

sed / awk:替换子字符串中的空格[重复]

这个问题已经在这里有了答案 : 上个月关闭。 SED替换引号内的文本 (2个答案) 如何使用sed或awk转换此字符串: | "A rand0m s
3回复

AWK \\ SED在单个命令中同时替换字符串的^(开始)和$(end)

我一直在环顾四周,但是找不到同时使用AWK和SED的方法 。 我想知道是否有一种方法可以在单个命令中替换字符串的开头和结尾。 更具体地说 ,其中有一个包含很多单词的文件,我想在单词之前和之后添加一些内容。 谢谢罗伊