Awk 仅在两个关键字之间替换字符串

Awk 仅在两个关键字之间替换字符串,awk,sed,Awk,Sed,我有一个xml文件 我正在文件中搜索所有hrefs之间的并将其替换为authref 为了这个我试过了 awk '/<autor>/,/<\/autor>/ {gsub(/href/,"authref");}{print;}' awk'//,//{gsub(/href/,“authref”);}{print;} 此命令将替换完整文档中的HREF,而不仅仅是关键字/标记之间的HREF。 我做错了什么 导入txt的示例: …自动文本的名称更多文本awk和sed的问题在于它

我有一个xml文件 我正在文件中搜索所有
href
s之间的
并将其替换为
authref

为了这个我试过了

awk '/<autor>/,/<\/autor>/ {gsub(/href/,"authref");}{print;}'
awk'//,//{gsub(/href/,“authref”);}{print;}
此命令将替换完整文档中的HREF,而不仅仅是关键字/标记之间的HREF。 我做错了什么

导入txt的示例:


…自动文本的名称更多文本awk和sed的问题在于它们是面向行的,因此它们将匹配包含
的行,并替换行中的“href”所有位置,而不限于自动标记内

您的
Bild
标签没有右括号。使用XML解析器会向您指出这一点

$ xmlstarlet val file.xml
file.xml - invalid
修复后:

$ xmlstarlet val file.xml
file.xml - valid
$ xmlstarlet edit --rename '//autor/Bild/@href_fmt' --value authref_fmt file.xml
<?xml version="1.0"?>
<root>
  <autor>
    <autor_Name>name of the autor</autor_Name>
    <autor_infos>some more text</autor_infos>
    <Bild authref_fmt="pic/autor.jpg"/>
    <Fotocredit>credit infos</Fotocredit>
  </autor>
</root>
$xmlstarlet val file.xml
file.xml-有效
$xmlstarlet edit--rename'//autor/Bild/@href_fmt'--value authref_fmt file.xml
车长姓名
更多的文字
信用信息
要保留输入格式,请使用
xmlstarlet edit-O-p…


要将输出写回文件,请使用
xmlstarlet edit-L…

awk和sed的问题在于它们是面向行的,因此它们将匹配包含
的行,并替换行中的“href”所有地方,而不限于autor标记内

您的
Bild
标签没有右括号。使用XML解析器会向您指出这一点

$ xmlstarlet val file.xml
file.xml - invalid
修复后:

$ xmlstarlet val file.xml
file.xml - valid
$ xmlstarlet edit --rename '//autor/Bild/@href_fmt' --value authref_fmt file.xml
<?xml version="1.0"?>
<root>
  <autor>
    <autor_Name>name of the autor</autor_Name>
    <autor_infos>some more text</autor_infos>
    <Bild authref_fmt="pic/autor.jpg"/>
    <Fotocredit>credit infos</Fotocredit>
  </autor>
</root>
$xmlstarlet val file.xml
file.xml-有效
$xmlstarlet edit--rename'//autor/Bild/@href_fmt'--value authref_fmt file.xml
车长姓名
更多的文字
信用信息
要保留输入格式,请使用
xmlstarlet edit-O-p…


要将输出写回文件,请使用
xmlstarlet edit-L…
Awksed可能的双“地址”语义替换为单个“模式”语义。以下是与您正在做的工作相当的sed

sed '/<autor>/,/<\/autor>/ s/href/authref/g'
sed'//,//s/href/authref/g'
以下是awk的版本:

awk -v on=0 '
    /<autor>/   { on = 1 }
    on { gsub(/href/, "authref") }
    /<\/autor>/ { on = 0 }
    1'
awk-v on=0'
//{on=1}
在{gsub(/href/,“authref”)}
//{on=0}
1'

请注意,这两个都应该被视为快速黑客。。。无论是sed还是awk解决方案都不能保证与HTML/XML完美结合。最好使用适当支持XML解析的工具来完成这类工作。另一种方法是使用
xml2 | script | 2xml
预处理/后处理管道为基于行的处理器提供一种良好的平面文件格式。

Awksed可能的双“地址”语义替换为单个“模式”语义。以下是与您正在做的工作相当的sed

sed '/<autor>/,/<\/autor>/ s/href/authref/g'
sed'//,//s/href/authref/g'
以下是awk的版本:

awk -v on=0 '
    /<autor>/   { on = 1 }
    on { gsub(/href/, "authref") }
    /<\/autor>/ { on = 0 }
    1'
awk-v on=0'
//{on=1}
在{gsub(/href/,“authref”)}
//{on=0}
1'
请注意,这两个都应该被视为快速黑客。。。无论是sed还是awk解决方案都不能保证与HTML/XML完美结合。最好使用适当支持XML解析的工具来完成这类工作。另一种方法是使用
xml2 | script | 2xml
预处理/后处理管道,为基于行的处理器提供一种很好的平面文件格式。

/,//
并不意味着从
这个词到
这个词,相反,它表示从包含
一词的行到包含
一词的行。您的输入全部在一行上,因此您的替换发生在整个输入上

无论如何都不要使用范围表达式,因为它们会使琐碎的任务变得非常简短,但对于更有趣的事情,则需要完全重写或复制条件

在本例中,对于多字符RS和RT的GNU awk,它类似于(未测试,因为提供的示例不足以完全测试):

awk-vrs='''''!(NR%2){gsub(/href/,“authref”)}{ORS=RT}1'文件
这假设总是存在匹配的
..
对,它们不能嵌套(
..
),并且它们不会出现在所需的XML标记以外的上下文中(例如,它们不会出现在字符串或注释中)。

/,//
并不意味着从单词
到单词
,相反,它表示从包含
一词的行到包含
一词的行。您的输入全部在一行上,因此您的替换发生在整个输入上

无论如何都不要使用范围表达式,因为它们会使琐碎的任务变得非常简短,但对于更有趣的事情,则需要完全重写或复制条件

在本例中,对于多字符RS和RT的GNU awk,它类似于(未测试,因为提供的示例不足以完全测试):

awk-vrs='''''!(NR%2){gsub(/href/,“authref”)}{ORS=RT}1'文件

这假设始终存在匹配的
..
对,并且它们不能嵌套(
..
),并且它们不会出现在所需XML标记以外的上下文中(例如,它们不会出现在字符串或注释中)。

为什么要使用
awk
来处理XML?您不能使用像
xmllint
xmlstartet
这样的语法感知解析器?我已经用sed/awk构建了一个长字符串。现在我只需要再做一次改变。原来的脚本是5年前,我不习惯重写它。请添加样本输入和yo