Python 更改标记之间的文本-外壳脚本

Python 更改标记之间的文本-外壳脚本,python,regex,bash,sed,awk,Python,Regex,Bash,Sed,Awk,我有一个jsp文件,如下所示: <font color="#121212"> <br> Text 1 <br> Text 2 <br> </font> 文本1 文本2 有人知道我可以在shell脚本中调用一个快速的sed/awk命令,用预定义的变量替换“Text 1”和“Text 2”吗?Text1/2只是这个问题的占位符,那些标记之间的空间可以用任何东西填充 更新:更改标记以允许python中的建议。sed无法处理多行输

我有一个jsp文件,如下所示:

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


文本1
文本2
有人知道我可以在shell脚本中调用一个快速的sed/awk命令,用预定义的变量替换“Text 1”和“Text 2”吗?Text1/2只是这个问题的占位符,那些

标记之间的空间可以用任何东西填充


更新:更改标记以允许python中的建议。

sed无法处理多行输入。它一行一行地读

这里有一个技巧,但它需要一个分隔符,你知道它永远不会出现在“文本1”或“文本2”中(我使用了µ)

cat文件|tr'\n“µ”sed-e的/
µ[^µ]*µ
µ[^µ]*µ
/
µ您的文本1µ
µ您的文本2µ
/g'|tr“µ”\n
sed无法处理多行输入。它一行一行地读

这里有一个技巧,但它需要一个分隔符,你知道它永远不会出现在“文本1”或“文本2”中(我使用了µ)

cat文件|tr'\n“µ”sed-e的/
µ[^µ]*µ
µ[^µ]*µ
/
µ您的文本1µ
µ您的文本2µ
/g'|tr“µ”\n
尝试此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
awk'/尝试此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

awk'/我仍然建议使用另一种带有XML解析器的语言,比如Ruby。但这是一种使用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"
#/垃圾箱/垃圾箱
文件=temp.txt
TEXT1=“某些内容可能包含sed无法使用的字符。”
TEXT2=“某些内容可能包含sed无法使用的字符。”
awk-v text1=“$text1”-v text2=“$text2”-”
{
打印
如果(/^[:blank:][]*[:blank:][]*$/){
while(getline){
打印
如果(/^[:blank:][]*
[[:blank:][]*$/){ 打印文本1 while(getline){ 如果(/^[:blank:][]*
[[:blank:][]*$/){ 打印 打印文本2 while(getline){ 如果(/^[:blank:][]*(
|))[[:blank:][]*$/){ 打印 while(getline){ 打印 } } } } } } } } } “<”$FILE”

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

我仍然建议使用另一种带有XML解析器的语言,如Ruby。但这是一种使用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"
#/垃圾箱/垃圾箱
文件=temp.txt
TEXT1=“某些内容可能包含sed无法使用的字符。”
TEXT2=“某些内容可能包含sed无法使用的字符。”
awk-v text1=“$text1”-v text2=“$text2”-”
{
打印
如果(/^[:blank:][]*[:blank:][]*$/){
while(getline){
打印
如果(/^[:blank:][]*
[[:blank:][]*$/){ 打印文本1 while(getline){ 如果(/^[:blank:][]*
[[:blank:][]*$/){ 打印 打印文本2 while(getline){ 如果(/^[:blank:][]*(
|))[[:blank:][]*$/){ 打印 while(getline){ 打印 } } } } } } } } } “<”$FILE”

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

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

$ 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 text=“foo
酒吧
开始{
拆分(文本,t,/\n/)
}
/
/{ 如果(++c在t中){ 打印$0或t[c] f=1 } 否则{ f=0 } } !F "档案"

酒吧
否则:

$ 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>
$awk-v text1=“foo”-v text2=“bar”
开始{
t[++n]=text1
t[++n]=text2
}
/
/{ 如果(++c在t中){ 打印$0或t[c] f=1 } 否则{ f=0 } } !F "档案"

酒吧
请注意,如果将来需要在

之间添加更多的文本,并且代码的其余部分不会更改,则可以在
-v/BEGIN
部分中添加任意数量的替换文本块,它只替换数组
t
中填充的文本块


我看到了一些使用getline发布的答案。如果您正在考虑使用,请确保阅读并完全理解中描述的所有getline警告。我认为这个问题不适合使用getline解决。

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

$ 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 text=“foo
酒吧
开始{
拆分(文本,t,/\n/)
}
/
/{ 如果(++c在t中){ 打印$0或t[c] f=1 } 否则{ f=0 } } !F "档案"

酒吧
否则:

$ 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>
$awk-v text1=“foo”-v text2=“bar”
开始{
t[++n]=text1
t[++n]=text2
}
/
/{ 如果(++c在t中){ 打印$0或t[c] f=1 } 否则{ f=0 } } !F "档案"

酒吧
请注意,如果将来需要在

之间添加更多的文本,并且代码的其余部分不会更改,则可以在
-v/BEGIN
部分中添加任意数量的替换文本块-它只替换尽可能多的块