【问题标题】:Using RE with grep and sed for finding and replacing string in bash shell使用 RE 与 grep 和 sed 在 bash shell 中查找和替换字符串
【发布时间】:2017-05-14 02:23:47
【问题描述】:

我有数百个包含以下字符串的 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 命名空间名称的问题。

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

非常感谢!

【问题讨论】:

  • 您不应该尝试使用面向行的工具来操作 XML。请改用xmlstarlet 之类的东西。

标签: xml string bash sed grep


【解决方案1】:

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

#!/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 文件需要在一行中从 &lt;/&gt; 的 METADATAEXTENSION,如示例中所示。其他标签需要在其他分隔行上。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2011-09-04
      • 2014-01-13
      • 2018-02-24
      • 2020-11-15
      • 2014-02-11
      • 2013-03-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多