だから私は初めてシェルスクリプトに触れ、助けが必要です。だから私のCSVファイルで、IPとタイムスタンプの値がJSONログファイルの行エントリに何らかの方法で存在することを確認し、そうであれば、その特定のJSONログエントリを別のファイルに返したいと思います。すべてのIPアドレスで機能するように一般化しようとしています。サンプルCSVファイルは次のとおりです。
"clientip,""destip","dest_hostname","timestamp"
"127.0.0.1","0.0.0.0","randomhost","2023-09-09T04:18:22.542Z"
Jsonログファイルのサンプル行エントリ
{"log": "09-Sept-2023 rate-limit: info: client @xyz 127.0.0.1, "stream":"stderr", "time": 2023-09-09T04:18:22.542Z"}
これは、一致があるときにoutput.txtファイルに返すJSONログファイルの行です。 JSONファイルにはCSVと同じフィールドと組織はありません(clientip、destip、dest_hostname、timestampがありますが、少なくともJSONログファイルの行を一致する新しいファイルとして返すことができることを願っています)。 clientip(「info:client @xyz 127.0.0.1」で127.0.0.1を見たように)とタイムスタンプにすることもできます。
私はこれを試してコマンドをjoin file.csv xyz-json.log > output.txt
試しましたが、awk
役に立ちませんでした。助けてくれて本当にありがとうございます!
答え1
両方の入力ファイルの形式がそれぞれCSVファイルとJSONLファイルとして適切であると仮定すると、file.csv
Miller file.jsonl
(mlr
)を使用してJSONLファイルのキー値からクライアントIPを抽出し、log
それをキーとして使用できます。
2つのテスト入力ファイル(この例ではCSVファイルの引用符はオプションです):
"clientip","destip","dest_hostname","timestamp"
"127.0.0.1","0.0.0.0","randomhost","2023-09-09T04:18:22.542Z"
{"log": "09-Sept-2023 rate-limit: info: client @xyz 127.0.0.1", "stream": "stderr", "time": "2023-09-09T04:18:22.542Z"}
注文する:
mlr --jsonl --from file.jsonl \
put '$clientip = splita($log," ")[-1]' then \
join -f file.csv -i csv -j clientip then \
cut -f log,stream,time
まず、フィールド値をスペースに分割し、最後の単語を選択してclientip
JSONLデータにフィールドを作成します。log
その後、関係を実行します。内部結合JSONLデータを「右」データセット、CSVデータを「左」データセットとして機能します。clientip
結合キーを使用して結合が実行されます。
最後に、元のJSONLデータになかった結合によって生成されたレコードからすべてのフィールドを削除します(最初の2つのステップはすべてデータにキーを追加しました)。
結合キーに両方のファイルのタイムスタンプを使用しますか?これは2つのデータセットのフィールド名が異なるため、最も簡単な方法はデータでキーのJSONL値をtimestamp
使用することです(デフォルトでは次のものを使用します)。新しい名前でデータをコピーしたら、次のように結合します。time
time
mlr --jsonl --from file.jsonl \
put '$clientip = splita($log," ")[-1]; $timestamp = $time' then \
join -f file.csv -i csv -j clientip,timestamp then \
cut -f log,stream,time
上記の2つのコマンドのいずれかの出力はファイルにリダイレクトでき、質問の(修正された)データに基づいて出力はJSONL入力データと同じです。