【问题标题】:replace multi regex or words by sed one liner用 sed 一个衬里替换多个正则表达式或单词
【发布时间】:2019-07-05 19:03:51
【问题描述】:

Linux RH 5.11

GNU sed 4.1.5 版

我有以下文件,我想在 KEY 值以 ABC+ 的值替换为另一个(版本)值/em>DEFXYZ 通过运行一个命令(使用 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": "+"
  }
}

.

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

问题 1:

为什么sedABCDEFXYZ 代替实际的\2 值,我理解它应该是:", 或只是:" 即行输入该行中的 JSON 对象(带/不带任何空格/制表符)?

问题 2: 我怎样才能得到"ABC_PROJECT_Product": "+", 值:

"ABC_PROJECT_Product": "1.22.333.4444",

问题 3: 为什么要使用这个sed 解决问题 1 和 2(除了让它更快)。

sed -i "/.*\"${sed_regex}_PROJECT.*\"/ s/\(.*\".*\".*:.*\"\).*\(\".*\)/\11.22.333.4444\2/" ~/my-file.json;

可能是awk 可以轻松做到这一点?

【问题讨论】:

  • 1.22.333.4444 是从哪里来的?
  • 现在看.. 错字忘记包括了。
  • 不要使用 shell 实用程序操作 json。使用带有json 验证的工具,例如jq
  • 你可以安装/使用jq工具吗?
  • 什么?不批准jq,然后让开发人员松手,试图用shell工具破解json(从而创造一个无意中制造更严重漏洞的机会),听起来就像是在倒退思考:)

标签: regex bash awk sed word


【解决方案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 字符串未使用嵌套分组,并且正则表达式似乎与模式正确匹配。

【讨论】:

    【解决方案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)sed,因为您已经在使用 -E。或者,这将适用于每个 UNIX 机器上任何 shell 中的任何 awk:

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

    【讨论】:

    • 谢谢 Ed,我基本上使用了一个示例,并使用变量 sed_regex="somevalue" 来替换它在循环中设置为 IJK、LMN 或 ABC、DEF 的位置......所以不能使用单引号,否则,你的答案是完美的。
    • 不,您可以并且应该在脚本周围使用单引号,因为做任何其他事情都会不必要地将整个脚本暴露给 shell 以便在 sed 看到它之前进行解释。在脚本中使用shell变量的内容就是cmd 'foo'"$shellvar"'bar',例如sed_regex='ABC|DEF|GHI'; sed -E '/"('"$sed_regex"')_PROJECT/ s/[+]/11.22.333.4444/' file
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-21
    • 1970-01-01
    相关资源
    最近更新 更多