1

我有一个看起来像这样的 jsp 文件:

<font color="#121212">
<br>
Text 1 
<br>
Text 2
<br>
</font>

有谁知道我可以在我的 shell 脚本中调用一个快速的 sed/awk 命令来用预定义的变量替换“Text 1”和“Text 2”?Text1/2 只是这个问题的占位符,这些<br>标签之间的空间可以填充任何东西。

更新:更改标签以允许在 python 中提出建议。

4

4 回答 4

1

如果您有一些分隔符,您可以在替换文本块之间使用,例如换行符:

$ awk -v text="foo
bar" '
    BEGIN {
        split(text,t,/\n/)
    }
    /<br>/ {
        if (++c in t) {
            print $0 ORS t[c]
            f = 1
        }
        else {
            f = 0
        }
    }
    !f
' file
<font color="#121212">
<br>
foo
<br>
bar
<br>
</font>

除此以外:

$ awk -v text1="foo" -v text2="bar" '
    BEGIN {
        t[++n]=text1
        t[++n]=text2
    }
    /<br>/ {
        if (++c in t) {
            print $0 ORS t[c]
            f = 1
        }
        else {
            f = 0
        }
    }
    !f
' file
<font color="#121212">
<br>
foo
<br>
bar
<br>
</font>

请注意,-v/BEGIN如果您在未来需要替换的 s 之间有更多文本<br>并且其余代码不会更改,则可以在部分中添加任意数量的替换文本块 - 它只是替换尽可能多的块填充在数组中t

我看到一些使用 getline 发布的答案。如果您正在考虑使用它,请确保您阅读并完全理解http://awk.info/?tip/getline中描述的所有 getline 警告。恕我直言,这个问题不适合使用 getline 的解决方案。

于 2013-08-06T10:45:02.710 回答
0

sed 无法处理多行输入。它逐行读取。

所以这是一个技巧,但它需要一个你知道永远不会存在于“文本 1”或“文本 2”中的分隔符(我使用了 µ)

cat file | tr '\n' 'µ' | sed -e 's/<br>µ[^µ]*µ<br>µ[^µ]*µ<br>/<br>µYOUR TEXT 1µ<br>µYOUR TEXT 2µ<br>/g' | tr 'µ' '\n'
于 2013-08-06T09:37:19.490 回答
0

试试这个 awk 命令:

awk '/<font /{intag=1}
     /<\/font>/{intag=0 ;br=0}
     intag==1 && /<br>/{br++}
     {print}
     br==1{print "Foo"; getline}
     br==2{print "Bar"; getline}' file

此命令将在 1st 之后<br>Fooline 替换为 2nd 之后<br>的line Bar

于 2013-08-06T09:49:21.143 回答
0

我仍然建议使用另一种语言和像 Ruby 这样的 XML 解析器。但这是使用 shell 和 awk 的一种方法。

#!/bin/sh

FILE=temp.txt
TEXT1="Some things that may include characters not possible with sed."
TEXT2="Some things that may include characters not possible with sed."

awk -v text1="$TEXT1" -v text2="$TEXT2" -- '
    {
        print
        if (/^[[:blank:]]*<font .*>[[:blank:]]*$/) {
            while (getline) {
                print
                if (/^[[:blank:]]*<br>[[:blank:]]*$/) {
                    print text1
                    while (getline) {
                        if (/^[[:blank:]]*<br>[[:blank:]]*$/) {
                            print
                            print text2
                            while (getline) {
                                if (/^[[:blank:]]*(<br>|<\/font>)[[:blank:]]*$/) {
                                    print
                                    while (getline) {
                                        print
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
' < "$FILE"

如果您想更加严格,可以删除所有 [[:blank:]]* 的实例。

于 2013-08-06T09:52:23.717 回答