用 sed 替换文本并保留部分原始文本

用 sed 替换文本并保留部分原始文本

我正在尝试转换

<id>1</id>
<Name>ENTERPRISE RESOURCE PLANNING</Name>

到:

<column name="id">1</column>
<column name="Name">ENTERPRISE RESOURCE PLANNING</column>

我假设这项工作的最佳工具是sed,但是我不知道如何将部分原始文本保留在替换部分中。

如果我做:

$ sed -i 's/<.*>.*<.*>/<column name="\\1">\\2<\/column>/g' filename.xml

输出是:

<column name="\1">\2</column>
<column name="\1">\2</column>

或者从内部做类似的事情vi,它输出:

<column name=""></column>
<column name=""></column>

我怎样才能使\1\2被替换回原来的值?

答案1

您可以使用组,例如:

$ sed -i 's/<\(.*\)>\(.*\)<.*>/<column name="\1">\2<\/column>/g' filename.xml

RE 中最令人困惑的部分可能是它有多种语法风格。

例如sed和vim的使用基本正则表达式你必须引用()才能获得它们的元含义。

扩展正则表达式(例如 awk、egrep 等)您必须引用()才能获得字面意思。其他元字符也有类似的差异。

BRE 语义背后的基本原理()是,当您的大部分输入是 C 代码时,那么在元使用时必须引用括号会更实际。

答案2

使用xmlstarlet

  1. name向所有id和节点添加属性Name,并使用值idName根据需要添加。
  2. 将所有nameid节点重命名为column.
xmlstarlet ed \
    -s '//id'   -t attr -n name -v id \
    -s '//Name' -t attr -n name -v Name \
    -r '//id'   -v column \
    -r '//Name' -v column  file.xml

给定一个示例文档,例如

<root>
<id>1</id><Name>ENTERPRISE RESOURCE PLANNING</Name>
<id>2</id><Name>ENTERPRISE RESOURCE PLANNING (the return)</Name>
</root>

(请注意,节点之间的空格并不重要)这将导致

<?xml version="1.0"?>
<root>
  <column name="id">1</column>
  <column name="Name">ENTERPRISE RESOURCE PLANNING</column>
  <column name="id">2</column>
  <column name="Name">ENTERPRISE RESOURCE PLANNING (the return)</column>
</root>

相关内容