使用 awk 或 sed 删除 xml 文件中包含“/”和变量替换的目标搜索字符串周围的行
Use awk or sed to remove lines in xml file around target search string containing "/" and variable substitution
我有一个 XML 文件,里面的内容如下
<?xml version="1.0" encoding="UTF-8"?>
<FlexiPage xmlns="http://soap.sforce.com/2006/04/metadata">
<flexiPageRegions>
<itemInstances>
<componentInstance>
<componentInstanceProperties>
<name>collapsed</name>
<value>false</value>
</componentInstanceProperties>
...
</itemInstances>
<itemInstances>
<componentInstance>
<componentName>NameSpace:customList</componentName>
</componentInstance>
</itemInstances>
<mode>Replace</mode>
...
我正在尝试使用 awk
从文件中删除这些行。
我尝试运行以下脚本
namespace="NameSpace"
component="customList"
awk "NR==FNR{if (/<componentName>$namespace:$component<\/componentName>/) for (i=-2;i<=2;i++) del[NR+i]; next} !(FNR in del)" file file
但它不是剪切所需的行,而是在 xml 文件的开头切掉行
并产生以下输出
<?xml version="1.0" encoding="UTF-8"?>
<FlexiPage xmlns="http://soap.sforce.com/2006/04/metadata">
<flexiPageRegions>
</componentInstanceProperties>
...
</itemInstances>
<itemInstances>
<componentInstance>
<componentName>NameSpace:customList</componentName>
</componentInstance>
</itemInstances>
<mode>Replace</mode>
...
我尝试使用不同形式的变量替换,就像这样
awk -v x="<componentName>$namespace:$component<\/componentName>" "NR==FNR{if ([=14=] ~ x) for (i=-2;i<=2;i++) del[NR+i]; next} !(FNR in del)" file source.xml
还有这个
awk -v x="<componentName>$namespace:$component</componentName>" "NR==FNR{if ([=15=] ~ x) for (i=-2;i<=2;i++) del[NR+i]; next} !(FNR in del)" file source.xml
但都不起作用。有什么方法可以让它工作吗?
更新:删除行的期望结果
<itemInstances>
<componentInstance>
<componentName>NameSpace:customList</componentName>
</componentInstance>
</itemInstances>
结果文件如下所示
<?xml version="1.0" encoding="UTF-8"?>
<FlexiPage xmlns="http://soap.sforce.com/2006/04/metadata">
<flexiPageRegions>
<itemInstances>
<componentInstance>
<componentInstanceProperties>
<name>collapsed</name>
<value>false</value>
</componentInstanceProperties>
...
</itemInstances>
<mode>Replace</mode>
...
您上次尝试的唯一错误是:
- 您在 args 列表中只提供了
file
一次而不是两次
- 您在脚本周围使用了双引号而不是单引号。
在 awk 脚本周围使用双引号是非常、非常少的正确方法。
假设您定义了这些 shell 变量,如您的问题所示:
namespace='NameSpace'
component='customList'
这样做:
$ awk -v name="$namespace" -v comp="$component" 'NR==FNR{if ([=11=] ~ ("<componentName>"name":"comp"</componentName>")) for (i=-2;i<=2;i++) del[NR+i]; next} !(FNR in del)' file file
<?xml version="1.0" encoding="UTF-8"?>
<FlexiPage xmlns="http://soap.sforce.com/2006/04/metadata">
<flexiPageRegions>
<itemInstances>
<componentInstance>
<componentInstanceProperties>
<name>collapsed</name>
<value>false</value>
</componentInstanceProperties>
...
</itemInstances>
<mode>Replace</mode>
...
或者如果您愿意:
$ awk -v x="<componentName>${namespace}:${component}</componentName>" 'NR==FNR{if ([=12=] ~ x) for (i=-2;i<=2;i++) del[NR+i]; next} !(FNR in del)' file file
<?xml version="1.0" encoding="UTF-8"?>
<FlexiPage xmlns="http://soap.sforce.com/2006/04/metadata">
<flexiPageRegions>
<itemInstances>
<componentInstance>
<componentInstanceProperties>
<name>collapsed</name>
<value>false</value>
</componentInstanceProperties>
...
</itemInstances>
<mode>Replace</mode>
...
参见 How do I use shell variables in an awk script?。
我将 awk 变量的 shell 变量 namespace
缩短为 name
因为 namespace
是 GNU awk 中的保留字,所以您不能使用它作为变量名。
我有一个 XML 文件,里面的内容如下
<?xml version="1.0" encoding="UTF-8"?>
<FlexiPage xmlns="http://soap.sforce.com/2006/04/metadata">
<flexiPageRegions>
<itemInstances>
<componentInstance>
<componentInstanceProperties>
<name>collapsed</name>
<value>false</value>
</componentInstanceProperties>
...
</itemInstances>
<itemInstances>
<componentInstance>
<componentName>NameSpace:customList</componentName>
</componentInstance>
</itemInstances>
<mode>Replace</mode>
...
我正在尝试使用 awk
从文件中删除这些行。
我尝试运行以下脚本
namespace="NameSpace"
component="customList"
awk "NR==FNR{if (/<componentName>$namespace:$component<\/componentName>/) for (i=-2;i<=2;i++) del[NR+i]; next} !(FNR in del)" file file
但它不是剪切所需的行,而是在 xml 文件的开头切掉行 并产生以下输出
<?xml version="1.0" encoding="UTF-8"?>
<FlexiPage xmlns="http://soap.sforce.com/2006/04/metadata">
<flexiPageRegions>
</componentInstanceProperties>
...
</itemInstances>
<itemInstances>
<componentInstance>
<componentName>NameSpace:customList</componentName>
</componentInstance>
</itemInstances>
<mode>Replace</mode>
...
我尝试使用不同形式的变量替换,就像这样
awk -v x="<componentName>$namespace:$component<\/componentName>" "NR==FNR{if ([=14=] ~ x) for (i=-2;i<=2;i++) del[NR+i]; next} !(FNR in del)" file source.xml
还有这个
awk -v x="<componentName>$namespace:$component</componentName>" "NR==FNR{if ([=15=] ~ x) for (i=-2;i<=2;i++) del[NR+i]; next} !(FNR in del)" file source.xml
但都不起作用。有什么方法可以让它工作吗?
更新:删除行的期望结果
<itemInstances>
<componentInstance>
<componentName>NameSpace:customList</componentName>
</componentInstance>
</itemInstances>
结果文件如下所示
<?xml version="1.0" encoding="UTF-8"?>
<FlexiPage xmlns="http://soap.sforce.com/2006/04/metadata">
<flexiPageRegions>
<itemInstances>
<componentInstance>
<componentInstanceProperties>
<name>collapsed</name>
<value>false</value>
</componentInstanceProperties>
...
</itemInstances>
<mode>Replace</mode>
...
您上次尝试的唯一错误是:
- 您在 args 列表中只提供了
file
一次而不是两次 - 您在脚本周围使用了双引号而不是单引号。
在 awk 脚本周围使用双引号是非常、非常少的正确方法。
假设您定义了这些 shell 变量,如您的问题所示:
namespace='NameSpace'
component='customList'
这样做:
$ awk -v name="$namespace" -v comp="$component" 'NR==FNR{if ([=11=] ~ ("<componentName>"name":"comp"</componentName>")) for (i=-2;i<=2;i++) del[NR+i]; next} !(FNR in del)' file file
<?xml version="1.0" encoding="UTF-8"?>
<FlexiPage xmlns="http://soap.sforce.com/2006/04/metadata">
<flexiPageRegions>
<itemInstances>
<componentInstance>
<componentInstanceProperties>
<name>collapsed</name>
<value>false</value>
</componentInstanceProperties>
...
</itemInstances>
<mode>Replace</mode>
...
或者如果您愿意:
$ awk -v x="<componentName>${namespace}:${component}</componentName>" 'NR==FNR{if ([=12=] ~ x) for (i=-2;i<=2;i++) del[NR+i]; next} !(FNR in del)' file file
<?xml version="1.0" encoding="UTF-8"?>
<FlexiPage xmlns="http://soap.sforce.com/2006/04/metadata">
<flexiPageRegions>
<itemInstances>
<componentInstance>
<componentInstanceProperties>
<name>collapsed</name>
<value>false</value>
</componentInstanceProperties>
...
</itemInstances>
<mode>Replace</mode>
...
参见 How do I use shell variables in an awk script?。
我将 awk 变量的 shell 变量 namespace
缩短为 name
因为 namespace
是 GNU awk 中的保留字,所以您不能使用它作为变量名。