用sed一支衬纸替换多条正则表达式或单词

时间:2019-07-05 19:03:51

标签: regex bash awk sed word

Linux RH 5.11

GNU sed版本4.1.5

我有以下文件,其中我要用 KEY 值以 开头的所有行的另一个(版本)值替换+的值ABC DEF XYZ (使用{{1 }}在进行基于自动换行/正则表达式的匹配时对单词进行分组。

sed

linux_user@linux_server123 [ ~ ] 18:37:18 :9152> cp ~/my-file.json ~/BKUP-my-file.json; cat ~/my-file.json 
{
  "versions": {
    "ABC_PROJECT_Product": "+",
    "IGNORE1_PROJECT_Product": "1.8.0.1371",
    "DEF_PROJECT_Product": "+",
    "XYZ_PROJECT_Product": "+",
    "IGNORE2_PROJECT_Product": "1.1.0.830",

    "ABC_PROJECTGlobal": "+",
    "DEF_PROJECTGlobal": "+",
    "IGNORE2_PROJECTGlobal": "1.1.0.830",

    "ABC_PROJECTGlobalSSD": "+",
    "DEF_PROJECTGlobalSSD": "+",

    "ABC_PROJECT_ProductSSD": "+",
    "IGNORE3_PROJECT_ProductSSD": "1.0.0.4913",
    "DEF_PROJECT_ProductSSD": "+",

    "ABC_PROJECTLocalREBS": "+",
    "IGNORE4_PROJECTLocalREBS": "1.1.0.865",

    "ABC_PROJECT_ProductODNS": "+",
    "IGNORE3_PROJECT_ProductODNS": "1.0.0.4913",
    "DEF_PROJECT_ProductODNS": "+",

    "ABC_PROJECT_ProductIDNS": "+",
    "DEF_PROJECT_ProductIDNS": "+",
    "IGNORE2_PROJECT_ProductIDNSS": "1.1.0.830",

    "ABC_PROJECTGlobalIDNS": "+",
    "DEF_PROJECTGlobalIDNS": "+",

    "ABC_PROJECTGlobalODNS": "+",
    "DEF_PROJECTGlobalODNS": "+",

    "ABC_PROJECTLocalSpecial": "+",
    "IGNORE4_PROJECTLocalSpecial": "1.1.0.865",

    "ABC_PROJECT_ProductSpecial": "+",
    "IGNORE5_PROJECT_ProductSpecial": "2.1.0.683",
    "DEF_PROJECT_ProductSpecial": "+",

    "ABC_PROJECTGlobalSpecial": "+"
  }
}

问题1:

为什么cp ~/BKUP-my-file.json ~/my-file.json; sed_regex="\(ABC\|DEF\|XYZ\)"; sed -i "s/\(.*\"${sed_regex}_PROJECT.*\".*:.*\"\).*\(\".*\)/\11.22.333.4444\2/" ~/my-file.json; sed -n "/.*\(ABC\|DEF\|XYZ\)_PROJECT.*/p" ~/my-file.json "ABC_PROJECT_Product": "1.22.333.4444ABC "DEF_PROJECT_Product": "1.22.333.4444DEF "XYZ_PROJECT_Product": "1.22.333.4444XYZ "ABC_PROJECTGlobal": "1.22.333.4444ABC "DEF_PROJECTGlobal": "1.22.333.4444DEF "ABC_PROJECTGlobalSSD": "1.22.333.4444ABC "DEF_PROJECTGlobalSSD": "1.22.333.4444DEF "ABC_PROJECT_ProductSSD": "1.22.333.4444ABC "DEF_PROJECT_ProductSSD": "1.22.333.4444DEF "ABC_PROJECTLocalREBS": "1.22.333.4444ABC "ABC_PROJECT_ProductODNS": "1.22.333.4444ABC "DEF_PROJECT_ProductODNS": "1.22.333.4444DEF "ABC_PROJECT_ProductIDNS": "1.22.333.4444ABC "DEF_PROJECT_ProductIDNS": "1.22.333.4444DEF "ABC_PROJECTGlobalIDNS": "1.22.333.4444ABC "DEF_PROJECTGlobalIDNS": "1.22.333.4444DEF "ABC_PROJECTGlobalODNS": "1.22.333.4444ABC "DEF_PROJECTGlobalODNS": "1.22.333.4444DEF "ABC_PROJECTLocalSpecial": "1.22.333.4444ABC "ABC_PROJECT_ProductSpecial": "1.22.333.4444ABC "DEF_PROJECT_ProductSpecial": "1.22.333.4444DEF "ABC_PROJECTGlobalSpecial": "1.22.333.4444ABC sedABCDEF代替实际的XYZ值,我知道应该是:{{1 }}还是:\2,即该行中JSON对象中的行条目(有/没有任何空格/制表符)?

问题2: 如何获得",的值:

"

问题3: 任何使用此"ABC_PROJECT_Product": "+",的原因为何都解决了问题1和2(除了使其更快了)。

"ABC_PROJECT_Product": "1.22.333.4444",

也许sed可以轻松做到这一点?

2 个答案:

答案 0 :(得分:2)

@cdub answered your 3 questions,但这是您要尝试的吗?

$ sed -E '/"(ABC|DEF|GHI)_PROJECT/ s/[+]/11.22.333.4444/' file
{
  "versions": {
    "ABC_PROJECT_Product": "11.22.333.4444",
    "IGNORE1_PROJECT_Product": "1.8.0.1371",
    "DEF_PROJECT_Product": "11.22.333.4444",
    "XYZ_PROJECT_Product": "+",
    "IGNORE2_PROJECT_Product": "1.1.0.830",

    "ABC_PROJECTGlobal": "11.22.333.4444",
    "DEF_PROJECTGlobal": "11.22.333.4444",
    "IGNORE2_PROJECTGlobal": "1.1.0.830",

    "ABC_PROJECTGlobalSSD": "11.22.333.4444",
    "DEF_PROJECTGlobalSSD": "11.22.333.4444",

    "ABC_PROJECT_ProductSSD": "11.22.333.4444",
    "IGNORE3_PROJECT_ProductSSD": "1.0.0.4913",
    "DEF_PROJECT_ProductSSD": "11.22.333.4444",

    "ABC_PROJECTLocalREBS": "11.22.333.4444",
    "IGNORE4_PROJECTLocalREBS": "1.1.0.865",

    "ABC_PROJECT_ProductODNS": "11.22.333.4444",
    "IGNORE3_PROJECT_ProductODNS": "1.0.0.4913",
    "DEF_PROJECT_ProductODNS": "11.22.333.4444",

    "ABC_PROJECT_ProductIDNS": "11.22.333.4444",
    "DEF_PROJECT_ProductIDNS": "11.22.333.4444",
    "IGNORE2_PROJECT_ProductIDNSS": "1.1.0.830",

    "ABC_PROJECTGlobalIDNS": "11.22.333.4444",
    "DEF_PROJECTGlobalIDNS": "11.22.333.4444",

    "ABC_PROJECTGlobalODNS": "11.22.333.4444",
    "DEF_PROJECTGlobalODNS": "11.22.333.4444",

    "ABC_PROJECTLocalSpecial": "11.22.333.4444",
    "IGNORE4_PROJECTLocalSpecial": "1.1.0.865",

    "ABC_PROJECT_ProductSpecial": "11.22.333.4444",
    "IGNORE5_PROJECT_ProductSpecial": "2.1.0.683",
    "DEF_PROJECT_ProductSpecial": "11.22.333.4444",

    "ABC_PROJECTGlobalSpecial": "11.22.333.4444"
  }
}

上面的代码需要使用GNU(或OSX / BSD),因为您已经在-E中使用了它。或者,这将与每个UNIX框上任何外壳中的任何awk一起使用:

awk '/"(ABC|DEF|XYZ)_PROJECT/{sub(/[+]/,"11.22.333.4444")} 1' file

答案 1 :(得分:1)

问题1:

sed字符串具有嵌套分组,因此\2指向\(ABC\|DEF\|XYZ\)。这就是为什么我们在每一行的末尾看到ABC,DEF等。通过用替换的sed_regex变量重写sed字符串,我们可以更清楚地看到嵌套:

sed "s/\(.*\"\(ABC\|DEF\|XYZ\)_PROJECT.*\".*:.*\"\).*\(\".*\)/\11.22.333.4444\2/"

问题2:

类似的事情可能起作用:

sed_regex="\(ABC\|DEF\|XYZ\)"; sed "s/$sed_regex\(_PROJECT.*\)\("+"\)/\1\211.22.333.4444/g"

问题3:

OP中修改后的sed字符串未使用嵌套分组,并且正则表达式似乎与模式正确匹配。