Удалить записи в файле, если такая же запись существует в главном файле

Вообще говоря, простой способ кавычки строки (например, команды оболочки), которая может содержать произвольные символы, это:[12151]Заменить все одиночные кавычки [11881]'[11882] в строке на 4-символьную последовательность [11883]'\''[11884]. [12152]Поместите одиночные кавычки [11885]'...'[11886] вокруг строки. [12153]Смотрите [11791]Обертка команды, которая включает в себя одинарные и двойные кавычки для другой команды[11792] более подробно.[12154]Таким образом (с оптимизацией по последнему символу, которая оказывается одинарной кавычкой):[12155]Однако, вместо того, чтобы останавливаться на таких сложностях, просто сделайте это функцией.[12156]Или сделайте это сценарием [11793]Сценарий[11794]..
2
24.07.2015, 21:32
3 ответа

Итак, я скопировал вашу нижнюю часть в два файла.

Файл 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,
        }
    }
}

Эта команда разбита следующим образом:

  1. grep -Ev '[{}] | ^ $' file1

    • Здесь мы просим grep напечатать каждая строка в file1 , которая не соответствует ни символу {, ни символу } , но должна соответствовать как минимум одному символу.
    • Его результат выглядит так:

        "section01Lev01_01": true, 
       "section01Lev01_012": true, 
       "section01Lev01_02": true 
       
  2. 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 .

Попробуйте несколько, и, возможно, вы найдете тот, который вам подходит.

0
27.01.2020, 22:54

Может быть лучше использовать инструменты, специализированные для 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: {
    }
}
0
27.01.2020, 22:54

Как отмечалось в других разделах этой страницы, надежным и эффективным способом решения проблемы является использование инструмента с поддержкой 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
  }
}
0
27.01.2020, 22:54

Теги

Похожие вопросы