用 sed one liner 替换多个正则表达式或单词
replace multi regex or words by sed one liner
Linux RH 5.11
GNU sed
版本 4.1.5
我有以下文件,我想将 +
的值替换为所有行的另一个(版本)值,其中 KEY 值以 ABC, DEF 或 XYZ 通过 运行 一个命令(使用 sed
组词能力,同时进行基于词 wrap/regex 的匹配)。
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.*\".*:.*\"\).*\(\".*\)/.22.333.4444/" ~/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
问题一:
为什么 sed
用 ABC
或 DEF
或 XYZ
代替实际的 </code> 值,据我所知应该是:<code>",
或只是:"
即在该行中的 JSON 对象(with/without 任何 space/tabs)中的行条目?
问题二:
如何获得 "ABC_PROJECT_Product": "+",
值:
"ABC_PROJECT_Product": "1.22.333.4444",
问题 3:
到底为什么使用这个 sed
解决了问题 1 和 2(除了让它更快 duh)。
sed -i "/.*\"${sed_regex}_PROJECT.*\"/ s/\(.*\".*\".*:.*\"\).*\(\".*\)/.22.333.4444/" ~/my-file.json;
可能 awk
可以轻松做到这一点?
问题 #1:
sed 字符串有嵌套分组,所以 </code> 指的是 <code>\(ABC\|DEF\|XYZ\)
。这就是我们在每行末尾看到 ABC、DEF 等的原因。我们可以更清楚地看到 re-writing 替换了 sed_regex 变量的 sed 字符串的嵌套:
sed "s/\(.*\"\(ABC\|DEF\|XYZ\)_PROJECT.*\".*:.*\"\).*\(\".*\)/.22.333.4444/"
问题#2:
类似这样的方法可行:
sed_regex="\(ABC\|DEF\|XYZ\)"; sed "s/$sed_regex\(_PROJECT.*\)\("+"\)/1.22.333.4444/g"
问题 #3:
OP 中修改后的 sed 字符串未使用嵌套分组,正则表达式似乎与模式正确匹配。
但这是你想要做的吗?
$ 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
Linux RH 5.11
GNU sed
版本 4.1.5
我有以下文件,我想将 +
的值替换为所有行的另一个(版本)值,其中 KEY 值以 ABC, DEF 或 XYZ 通过 运行 一个命令(使用 sed
组词能力,同时进行基于词 wrap/regex 的匹配)。
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.*\".*:.*\"\).*\(\".*\)/.22.333.4444/" ~/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
问题一:
为什么 sed
用 ABC
或 DEF
或 XYZ
代替实际的 </code> 值,据我所知应该是:<code>",
或只是:"
即在该行中的 JSON 对象(with/without 任何 space/tabs)中的行条目?
问题二:
如何获得 "ABC_PROJECT_Product": "+",
值:
"ABC_PROJECT_Product": "1.22.333.4444",
问题 3:
到底为什么使用这个 sed
解决了问题 1 和 2(除了让它更快 duh)。
sed -i "/.*\"${sed_regex}_PROJECT.*\"/ s/\(.*\".*\".*:.*\"\).*\(\".*\)/.22.333.4444/" ~/my-file.json;
可能 awk
可以轻松做到这一点?
问题 #1:
sed 字符串有嵌套分组,所以 </code> 指的是 <code>\(ABC\|DEF\|XYZ\)
。这就是我们在每行末尾看到 ABC、DEF 等的原因。我们可以更清楚地看到 re-writing 替换了 sed_regex 变量的 sed 字符串的嵌套:
sed "s/\(.*\"\(ABC\|DEF\|XYZ\)_PROJECT.*\".*:.*\"\).*\(\".*\)/.22.333.4444/"
问题#2:
类似这样的方法可行:
sed_regex="\(ABC\|DEF\|XYZ\)"; sed "s/$sed_regex\(_PROJECT.*\)\("+"\)/1.22.333.4444/g"
问题 #3:
OP 中修改后的 sed 字符串未使用嵌套分组,正则表达式似乎与模式正确匹配。
$ 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