2016-12-29 113 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