使用RE和grep和sed来查找和替换bash shell中的字符串

时间:2016-12-29 18:18:22

标签: xml string bash sed grep

我有数百个包含以下字符串的xml文件:

<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命名空间名称的问题。

如果你指出我正确的方向,我感激不尽

非常感谢!

2 个答案:

答案 0 :(得分: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,如示例中所示。其他标签需要在其他分隔线上。

答案 1 :(得分:0)

您可以匹配您想要的部分:

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