複数行を削除

複数行を削除

jsonファイルのリストから特定のコードセクション/行を削除するコマンドラインインタフェースを作成しようとしています。ところで、jsonファイルはホームディレクトリのサブフォルダにあります。

私はこれについて非常に新しいものですが、これはこれまで思い出せるコードです。find -name "*.json" | xargs sed -i "map"しかし、私が持っているjsonファイルのいくつかは少し異なる形式です。

これまでのリストには、次の2つの形式が表示されます。

{
    "tags": {}, 
    "map": {
        "KPA": {
            "State": True, 
            "namespace": "KPA01"
        }
    }
}

または

{
    "tags": {
        "type": [
            "char"
        ], 
        "dynamic": true
    }, 
    "map": {
        "KPA01": {
           "State": True, 
            "namespace": "KPA01"
        }
    }
}

デフォルトでは、マップ部分を省略してラベル部分のみを表示しようとしていますが、[]カンマや / があるので{}難しいです。したがって、私の出力は次のようになります。

{
    "tags": {}
}

または

{
    "tags": {
        "type": [
            "char"
        ], 
        "dynamic": true
    }
}

コマンドラインインターフェイスでこれを実行できますか? jqがこれを行うことができると聞きましたが、それを実行しようとすると端末jq '.map' test.jsonに閉じ込められます。parse error: ':' not as part of an object at line 2, column 11同様に、私が使用してもエラーが発生しているようです。JQプレイオンライン..

どんなアイデアがありますか?

答え1

まず、True次のように変更しますtrue。全体的に、これはかなりうまく機能します。

#!/usr/bin/python
import sys
import json

inputfile = sys.argv[1]
with open(inputfile,'r') as myfile:
    obj = json.loads(myfile.read().replace('True','true'))
    if "map" in obj:
        del obj["map"]
    json.dump(obj,sys.stdout,indent=4,separators=(',',': '))

これは標準出力に書き込まれます。

編集:以前の内部バージョンは少し危険なようです。これを行う方が良いです。

#!/usr/bin/python
import sys
import json

inputfile = sys.argv[1]
with open(inputfile,'r') as myfile:
    obj = json.loads(myfile.read().replace('True','true'))
    if "map" in obj:
        del obj["map"]
with open(inputfile,'w') as myfile:
    json.dump(obj,myfile,indent=4,separators=(',',': '))

スクリプトは実際に有効なJSONが何であるかを知っているため、予測不能な出力を生成するのではなく、誤ったコードが見つかると例外が発生します。

これはPython 3で動作します。

編集2:

任意の方法でオブジェクトを変更できます。 Jsonの目的は、オブジェクトを直列化することです。これを連想配列として扱い、必要な値を指定します。たとえば、次のようにできます。

#add a new string on the "ground" level
obj["new_key"]="lol"
#add a new subarray, with properties of different types
obj["this_is_array"]={"a": 3, "b": 16, "c": "string", "d": False }
#modify the value of existing field
obj["new_key"]="new value"
#insert into subarray (test if it exists first)
if "this_is_array" in obj:
    obj["this_is_array"]["e"]=42

答え2

処理すると本物>本物他の場所で言及してjqツールをインポートすると、次のことができます。

jq '{tags}' <infile

たとえば、例の1つをマイクリップボードにコピーした後:

xsel -bo | sed 's/True/true/g' | jq '{tags}'

出力:

{
  "tags": {
    "type": [
      "char"
    ],
    "dynamic": true
  }
}

答え3

同じエラーが見つかりました。

parse error: Invalid numeric literal at line 5, column 26

慣れないしかし、私の考えでは、True小文字で入力する必要がありますtrue実行することができます。1行に変更したら、それを使用して次のキーをjqフィルタリングします。map

perl -pe 's/(\W)T(rue)/$1t$2/g' file1.json | ./jq 'del(.map)'

最初の例では、結果は次のようになります。

{
  "tags": {}
}

そして:

perl -pe 's/(\W)T(rue)/$1t$2/g' file2.json | ./jq 'del(.map)'

2番目の結果は次のとおりです。

{
  "tags": {
    "type": [
      "char"
    ],
    "dynamic": true
  }
}

答え4

質問は古いですが、オプションの完成度のためにここにあります。ユナイテッドTC以下に基づくソリューション:

bash $ jtc -pw'<map>l+0' input.json
{
   "tags": {
      "dynamic": true,
      "type": [
         "char"
      ]
   }
}
bash $ 
  • すべてのタグを見つけて"map"消去します(残りのjsonは維持しながら)。

関連情報