замените несколько регулярных выражений или слов на sed - PullRequest
0 голосов
/ 05 июля 2019

Linux RH 5.11

GNU sed версия 4.1.5

У меня есть следующий файл, в котором я хочу заменить значение + другим значением (версии) для всехстроки, в которых значение KEY начинается с ABC , DEF или XYZ , выполнив одну команду (используя 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:

Почему sed ставит ABC или DEF или XYZ вместо фактического значения \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 может сделать это легкоу

Ответы [ 2 ]

2 голосов
/ 06 июля 2019

@ cdub ответил на ваши 3 вопроса но вы пытаетесь это сделать?

$ 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. В качестве альтернативы это будет работать с любым awk в любой оболочке на каждом компьютере UNIX:

awk '/"(ABC|DEF|XYZ)_PROJECT/{sub(/[+]/,"11.22.333.4444")} 1' file
1 голос
/ 05 июля 2019

Вопрос № 1:

Строка sed имеет вложенную группировку, поэтому \2 относится к \(ABC\|DEF\|XYZ\).Вот почему мы видим ABC, DEF и т. Д. В конце каждой строки.Мы можем более ясно увидеть вложение, переписав строку sed с заменой переменной sed_regex:

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:

Пересмотренная строка sed в OP не использует вложенную группировку, и регулярное выражение, по-видимому, соответствует шаблону.

...