2016-12-29 81 views
1

我有数以百计的XML文件包含以下字符串:使用使用grep RE和sed查找和bash shell中替换字符串

<METADATAEXTENSION COMPONENTVERSION ="8006001" DATATYPE ="STRING" DESCRIPTION ="Name of the Salesforce.com object" DOMAINNAME ="Salesforce" ISCLIENTEDITABLE ="NO" ISCLIENTVISIBLE ="YES" ISREUSABLE ="YES" ISSHAREREAD ="NO" ISSHAREWRITE ="NO" MAXLENGTH ="255" NAME ="Object Type" VALUE ="MY_STRING_TO_FIND__TheRestOfTheString__c" VENDORNAME ="INFORMATICA"/> 

我需要找到上面的字符串,找到

MY_STRING_TO_FIND 

并将其替换为不同的值,例如

MY_STRING_TO_REPLACE 

所以最终结果应该是这样的:

<METADATAEXTENSION COMPONENTVERSION ="8006001" DATATYPE ="STRING" DESCRIPTION ="Name of the Salesforce.com object" DOMAINNAME ="Salesforce" ISCLIENTEDITABLE ="NO" ISCLIENTVISIBLE ="YES" ISREUSABLE ="YES" ISSHAREREAD ="NO" ISSHAREWRITE ="NO" MAXLENGTH ="255" NAME ="Object Type" VALUE ="MY_STRING_TO_REPLACE__TheRestOfTheString__c" VENDORNAME ="INFORMATICA"/> 

我创建了两个变量:

MY_STRING_TO_FIND=AAA 
MY_STRING_TO_REPLACE=BBB 

,并使用下面的命令来查找包含整个字符串我需要找到,然后相应地更换令牌的所有文件:

grep -l "<METADATAEXTENSION[\s]*[$MY_STRING_TO_FIND]*" my_dir_with_xml_files | xargs sed -i "s/\A<METADATAEXTENSION[\s=\"._/>a-zA-Z0-9]+VALUE[\s=\"]+$MY_STRING_TO_FIND[__a-zA-Z\"\s=/>]+/\A<METADATAEXTENSION[\s=\"._/>a-zA-Z0-9]+VALUE[\s=\"]+$MY_STRING_TO_REPLACE[__a-zA-Z\"\s=/>]+/g" 

但这是行不通的。

一个复杂因素是字符串$ MY_STRING_TO_FIND发生在每个xml文件的其他部分,我不能触及。所以我需要在sed表达式中找到特定的字符串,并仅在此字符串中进行替换。

我试过其他各种组合都无济于事......

我知道,双引号忽略RE但允许参数扩展和单引号把一切从字面上所以我不能扩大我的参数。所以我在这里输了一些关于如何处理我的情况。

本质上,我试图解决在Informatica中动态处理Salesforce名称空间名称的问题。

我很欣赏,如果你点我在正确的方向

非常感谢!

+0

你不应该试图操纵与面向行的工具XML。改为使用'xmlstarlet'之类的东西。 –

回答

2

你可以尝试bash脚本调用的sed这样的:

#!/bin/bash 

MY_STRING_TO_FIND=${1:-AAA} 
MY_STRING_TO_REPLACE=${2:-BBB} 
TARGETS=${3:-*.xml} 

sed -r "/<METADATAEXTENSION[^>]*${MY_STRING_TO_FIND}[^>]*>/ s/${MY_STRING_TO_FIND}/${MY_STRING_TO_REPLACE}/" ${TARGETS} 

你可以通过你的字符串作为$ 1,$ 2和$ 3文件模式。

如果脚本适用于某些测试数据,那么您希望使用GNU seds -i inplace选项或某些输出重定向来存储修改后的xml数据,而不是将其转储到控制台。

这里的s替换仅适用于与条件匹配的行,即您的xml文件需要在示例中给出的一行中从</>的METADATAEXTENSION。而其他标签需要在其他分隔线上。

+0

谢谢,拉斯,它的工作! – Pit

0

可以匹配你想要的部分:

sed -i "s/^\(<METADATAEXTENSION.*\)${MY_STRING_TO_FIND/\1${MY_STRING_TO_REPLACE}/" inputfiles