私は検索しましたが、何が間違っているのかわかりませんが、この質問に対する答えが見つかりませんでした。
すべてのテキストが1行で保存されるファイルがあります。パターンを見つけて、区切り文字までそのテキストの前後のすべてのテキストを削除する必要があります。
前任者。文書
[{"something":false,"more":"123","moresamerecord":"otherstuff"},{"something":false,"more":"abc","moresamerecord":"otherstuff"},{"something2":false,"more":"def","moresamerecord":"otherstuff"},{"something2":false,"more":"456","moresamerecord":"otherstuff"}]
これは、複数のレコードを含む単一行であることを覚えておいてください。 "abc"を見つけて、前のレコードと次のレコードの間のすべてのエントリを削除しようとしています。
予想される結果は次のとおりです。
[{"something":false,"more":"123","moresamerecord":"otherstuff"},{"something2":false,"more":"def","moresamerecord":"otherstuff"},{"something2":false,"more":"456","moresamerecord":"otherstuff"}]
私は努力しましたが、これを理解することはできません。どんな助けでも大変感謝します。
ベストアンサー1
すでに指摘したように、jq
このタイプのデータのためのツールがあります。ただし、jqは「オブジェクトのリストは角かっこで表される配列になければなりません」などの特定の構文制約を適用します。
ファイルがすでに有効なjsonであることを確認できない場合は、sedを使用して前処理することができます(結果をより簡単に表示し、精度を確認するため、jqを介して初期実行を実行します)。
$ sed 's/^/[/; s/,$/]/' data.txt | jq -r '.[]'
{
"something": false,
"more": "123",
"moresamerecord": "otherstuff"
}
{
"something": false,
"more": "abc",
"moresamerecord": "otherstuff"
}
{
"something2": false,
"more": "def",
"moresamerecord": "otherstuff"
}
{
"something2": false,
"more": "456",
"moresamerecord": "otherstuff"
}
それでは、一致するオブジェクトを削除するようにjqコマンドを変更してみましょう"more": "abc"
。
$ sed 's/^/[/; s/,$/]/' data.txt | jq -r '.[] | select(.more != "abc")'
{
"something": false,
"more": "123",
"moresamerecord": "otherstuff"
}
{
"something2": false,
"more": "def",
"moresamerecord": "otherstuff"
}
{
"something2": false,
"more": "456",
"moresamerecord": "otherstuff"
}
最後に、スペースなしでカンマ区切り文字を使用して1行に再圧縮するには、後処理ステップも必要になるようです。
$ sed 's/^/[/; s/,$/]/' data.txt | jq -r '.[] | select(.more != "abc")' | sed 's/}$/},/' | tr -d ' \n'
{"something":false,"more":"123","moresamerecord":"otherstuff"},{"something2":false,"more":"def","moresamerecord":"otherstuff"},{"something2":false,"more":"456","moresamerecord":"otherstuff"},