ベースファイルに同じエントリがある場合は、ファイルのエントリを削除します。

ベースファイルに同じエントリがある場合は、ファイルのエントリを削除します。

アカウント固有の構成ファイル(JSON形式)によって値をオーバーライドできるJSON基本構成ファイルがあります。基本ファイルの構造は次のとおりです。

{
    "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
    }
}

特定のアカウントのプロフィールは次のとおりです。

{
    "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
    }
}

参考までに、いくつかの値(section01Config.setting03、section02Config.setting01、section03Config.setting02)を除いて同じです。また、section4Configsブロック全体が両方のファイルで同じであることに注意してください。

アプリケーションは両方のファイルをロードし、アカウント設定とは異なるファイルでデフォルトファイルを上書きするため、同じファイルは必要ありません。

私がやりたいことは、そのようなアカウントファイルのディレクトリを繰り返し、基本ファイルと同じキーと値を持つ各ファイルのエントリを削除するスクリプトを持つことです。この例では、次のファイルが生成されます。

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

200以上のアカウントプロファイルがあり、手動で行うには一生かかるでしょう。どんな助けでも大変感謝します!

- - - 編集する - - - -

質問を単純化しようとしましたが、詳細が不足して回答に影響があるようです。

アカウントと構成JSONファイルは、セクションとその設定で構成されています。これは、JSONが上記のものより1レベル深いことを意味します。

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

ありがとうございます!

答え1

だから下の内容を2つのファイルにコピーしました。

ファイル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これは、標準入力パターンファイルをライン全体に一致する固定文字列パターンとして解釈するこの秒で読み取られます。--f-F-xv いいえ印刷物。したがって、この2番目は、grepfile1のtrue / false行と正確に一致しないfile2のすべての行を印刷します。

今stdinを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

いくつか試してみると、自分に合ったものを見つけることができます。

答え2

json専用のツールを使用する方が良いかもしれません。ジャックまたはジェイソン?しかし、したい場合は、andで
行うことができます。pastesed

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

またはawk

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

設定ファイルの各行について、デフォルトファイルの対応する(番号による)行を変数としてインポートし、その行がaデフォルトファイルの行と同じか異なる{場合は}印刷します。
結果:

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

答え3

このページの他の部分で述べたように、この問題を解決する強力で効率的な方法は、次のJSON認識ツールを使用することです。ジャック。元の問題に対する解決策を以下に提供します。変形を解決するために簡単に適用できます。

(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) マスターファイルとユーザー設定ファイルがそれぞれ master.json と user.json であるとします。

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

生産する:

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

関連情報