Eliminar inputs en file si existe la misma input en un file maestro

Tengo un file de configuration maestra JSON cuyo valor puede ser sobrescrito por el file de configuration de una count específica (también en JSON). El file maestro tiene esta estructura:

{ "section1Configs": { "setting01": true, "setting02": true, "setting03": false }, section2Configs: { "setting01": true, "setting02": true, "setting03": false }, section3Configs: { "setting01": true, "setting02": true, "setting03": false }, section4Configs: { "setting01": true, "setting02": true, "setting03": false } } 

El file de configuration para una count específica puede verse así:

 { "section1Configs": { "setting01": true, "setting02": true, "setting03": true }, section2Configs: { "setting01": false, "setting02": true, "setting03": false }, section3Configs: { "setting01": true, "setting02": false, "setting03": false }, section4Configs: { "setting01": true, "setting02": true, "setting03": false } } 

Tenga en count que son idénticos, excepto que ciertos valores (sección01Config.setting03, section02Config.setting01 y section03Config.setting02) son diferentes. Tenga en count también que todo el bloque section4Configs es el mismo en ambos files.

Los que son iguales no son necesarios ya que la aplicación carga ambos y sobrescribe el file principal con los que son diferentes en la configuration de la count.

Lo que me gustaría hacer es tener un script que itere a través de un directory de dichos files de counts y elimine la input en cada file que tenga la misma key y valor que el file maestro. De este ejemplo, terminaría con un file como este:

 { section1Configs: { setting03: true }, section2Configs: { setting01: false }, section3Configs: { setting02: false } } 

Hay más de 200 files de configuration de count y hacer esto manualmente tomará toda una vida. ¡Cualquier ayuda es muy apreciada!

—— EDIT ——-

Traté de mantener la pregunta simple, pero creo que un detalle faltante tendrá un impacto en la respuesta.

El file JSON de count y configuration consta de secciones y sus configuraciones correspondientes. Esto significa que el JSON es un nivel más profundo que el mencionado anteriormente:

 { "section1Configs": { "level1Settings": { "section01Lev01_01": true, "section01Lev01_012": true, "section01Lev01_02": true } } } 

¡Gracias!

Así que copié lo de abajo en dos files.

Archivo 1:

 { "section1Configs": { "level1Settings": { "section01Lev01_01": true, "section01Lev01_012": true, "section01Lev01_02": true } } } 

Y file 2 …

 { "section1Configs": { "level1Settings": { "section01Lev01_01": true, "section01Lev01_012": false, "section01Lev01_02": true } } } 

Solo se diferencian en la línea Level01_012 .

Entonces lo hice:

 grep -Ev '[{}]|^$' file1 | grep -Fxvf- file2 

 { "section1Configs": { "level1Settings": { "section01Lev01_012": false, } } } 

Ese command se divide de la siguiente manera:

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

    • Aquí le pedimos a grep que imprima cada línea del file1 que no concuerde con un carácter { personaje o un } , pero debe coincidir con al less un carácter.
    • Su salida se ve así:

        "section01Lev01_01": true, "section01Lev01_012": true, "section01Lev01_02": true 
  2. grep -Fxvf- file2

    • Esto es leído por este segundo grep que interpreta su patrón de input stdin, como un patrón de cadena completa, coincidencia de línea completa que no debería imprimirse a la salida. Y así este segundo grep imprime cada línea en el file2 que no coincide exactamente con las líneas verdadero / falso en el file1.

Ahora si tu grep no entiende - como stdin tenemos algunas opciones:

 grep -Ev '[{}]|^$' file1 | grep -Fxvf /dev/fd/0 file2 

… funcionará en la mayoría de los sistemas. Una opción similar es usar /dev/stdin , que también es bastante probable que funcione, aunque un poco less.

También hay una implementación específica de shell conocida como sustitución de processs que funciona exactamente de la misma manera …

 grep -Fxvf <(grep -Ev '[{}]|^$' file1) file2 

… que puede o no funcionar para usted dependiendo de su caparazón.

Otra posibilidad es …

 grep -Fxv "$(grep -Ev '[{}]|^$' file1)" file2 

… que puede o no funcionar para usted, dependiendo de qué tan grande sea la salida del command grep subbed.

Pruebe algunos y probablemente encontrará uno que funcione para usted.

¿Puede ser mejor usar herramientas especializadas para json como jq o jshon ?
Pero si lo desea, puede hacerlo con paste y sed

 paste config master | sed '/[{}]/! {/\(.\+\)\t\1/d;};s/\t.*//' 

o awk

 awk '{getline a < "master"} /[{}]/ || $0 != a' config 

para cada línea en config-file, obtiene la fila correspondiente (por número) del file maestro en la variable a y si la línea consiste en { o } o no es lo mismo con las del file maestro, imprímalo.
Resultado:

 { "section1Configs": { "setting03": true }, section2Configs: { "setting01": false, }, section3Configs: { "setting02": false, }, section4Configs: { } } 

Como se señaló en otra parte de esta página, una forma robusta y eficiente de resolver el problema es usar una herramienta compatible con JSON como jq . Lo siguiente proporciona una solución al problema original; se puede adaptar fácilmente para resolver variantes.

(1) Coloque lo siguiente en un file, digamos minusConfig.jq:

 def minus(o1;o2): o1 | with_entries( select(o2[.key] != .value) ); def minusConfig(o1;o2): networkinguce (o1|keys)[] as $key ({}; minus( o1[$key] ; o2[$key]) as $v | if $v == {} then . else . + {($key): $v} end ); minusConfig($user; $master) 

(2) Suponiendo que los files de configuration maestra y de usuario son master.json y user.json respectivamente,

 $ jq -n --arg master master.json --arg user user.json -f minusConfig.jq 

produce:

 { "section1Configs": { "setting03": true }, "section2Configs": { "setting01": false }, "section3Configs": { "setting02": false } }