Вообще говоря, простой способ кавычки строки (например, команды оболочки), которая может содержать произвольные символы, это:[12151]Заменить все одиночные кавычки [11881]'[11882] в строке на 4-символьную последовательность [11883]'\''[11884]. [12152]Поместите одиночные кавычки [11885]'...'[11886] вокруг строки. [12153]Смотрите [11791]Обертка команды, которая включает в себя одинарные и двойные кавычки для другой команды[11792] более подробно.[12154]Таким образом (с оптимизацией по последнему символу, которая оказывается одинарной кавычкой):[12155]Однако, вместо того, чтобы останавливаться на таких сложностях, просто сделайте это функцией.[12156]Или сделайте это сценарием [11793]Сценарий[11794].
. Итак, я скопировал вашу нижнюю часть в два файла.
Файл 1:
{
"section1Configs": {
"level1Settings": {
"section01Lev01_01": true,
"section01Lev01_012": true,
"section01Lev01_02": true
}
}
}
И Файл 2 ...
{
"section1Configs": {
"level1Settings": {
"section01Lev01_01": true,
"section01Lev01_012": false,
"section01Lev01_02": true
}
}
}
Они различаются только строкой Level01_012
.
Тогда я сделал:
grep -Ev '[{}]|^$' file1 | grep -Fxvf- file2
{
"section1Configs": {
"level1Settings": {
"section01Lev01_012": false,
}
}
}
Эта команда разбита следующим образом:
grep -Ev '[{}] | ^ $' file1
grep
напечатать каждая строка в file1
, которая не соответствует ни символу {
, ни символу }
, но должна соответствовать как минимум одному символу. Его результат выглядит так:
"section01Lev01_01": true,
"section01Lev01_012": true,
"section01Lev01_02": true
grep -Fxvf- file2
grep
, который интерпретирует его -
входной шаблон stdin -f
файл как - F
шаблон фиксированной строки -x
соответствие всей строки, которое должно - v
не печатать для вывода. И поэтому этот второй grep
печатает каждую строку в файле2, которая не совсем соответствует истинным / ложным строкам в файле1. Теперь, если ваш grep
не понимает -
как стандартный ввод, у нас есть несколько вариантов:
grep -Ev '[{}]|^$' file1 | grep -Fxvf /dev/fd/0 file2
... будет работать в большинстве систем. Похожий вариант - использовать / dev / stdin
, что тоже, скорее всего, сработает, если немного меньше.
Существует также реализация для конкретной оболочки, известная как подстановка процесса , которая работает примерно так же ...
grep -Fxvf <(grep -Ev '[{}]|^$' file1) file2
... которая может работать или не работать для вас в зависимости от ваша оболочка.
Другая возможность ...
grep -Fxv "$(grep -Ev '[{}]|^$' file1)" file2
...что может или не может сработать для вас, в зависимости от того, насколько велик вывод команды grep
.
Попробуйте несколько, и, возможно, вы найдете тот, который вам подходит.
Может быть лучше использовать инструменты, специализированные для json, например jq или jshon ?
{{1 }} Но при желании это можно сделать с помощью paste
и sed
paste config master | sed '/[{}]/! {/\(.\+\)\t\1/d;};s/\t.*//'
или awk
awk '{getline a < "master"} /[{}]/ || $0 != a' config
для каждой строки в config-файле получает соответствующую (по номеру) строку из мастер-файла в переменную a
и если строка состоит из {
или }
или не совпадает с таковыми из мастер-файла, распечатайте ее.
Результат:
{
"section1Configs": {
"setting03": true
},
section2Configs: {
"setting01": false,
},
section3Configs: {
"setting02": false,
},
section4Configs: {
}
}
Как отмечалось в других разделах этой страницы, надежным и эффективным способом решения проблемы является использование инструмента с поддержкой JSON, такого как jq. Ниже приводится решение исходной задачи; оно может быть легко адаптировано к вариантам решения.
(1) Поместите в файл, скажем, minusConfig.jq:
def minus(o1;o2):
o1 | with_entries( select(o2[.key] != .value) );
def minusConfig(o1;o2):
reduce (o1|keys)[] as $key ({};
minus( o1[$key] ; o2[$key]) as $v
| if $v == {} then . else . + {($key): $v} end );
minusConfig($user; $master)
(2) Предположим, что ведущий и пользовательский конфигурационные файлы являются ведущим.json и пользователем. json соответственно,
$ jq -n --arg master master.json --arg user user.json -f minusConfig.jq
производит:
{
"section1Configs": {
"setting03": true
},
"section2Configs": {
"setting01": false
},
"section3Configs": {
"setting02": false
}
}