CSVファイルの分析・フィルタリングツール「Quilter-CSV」
概要
「Quilter-CSV」は、大容量のCSVファイルを高速に分析・フィルタリングが可能なツールです。
CLI/YAMLルールでCSVの加工が可能です。
下記は、イベントログのCSVファイルから'Event ID'が4624の行でフィルタし、'Date and Time'列でソートして先頭3行を標準出力する例です。
$ qsv load Security.csv - isin 'Event ID' 4624 - sort 'Date and Time' - head 3
shape: (3, 5)
┌─────────────┬───────────────────────┬─────────────────────────────────┬──────────┬───────────────┐
│ Level ┆ Date and Time ┆ Source ┆ Event ID ┆ Task Category │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ str ┆ str ┆ str ┆ i64 ┆ str │
╞═════════════╪═══════════════════════╪═════════════════════════════════╪══════════╪═══════════════╡
│ Information ┆ 10/6/2016 01:00:55 PM ┆ Microsoft-Windows-Security-Aud… ┆ 4624 ┆ Logon │
│ Information ┆ 10/6/2016 01:04:05 PM ┆ Microsoft-Windows-Security-Aud… ┆ 4624 ┆ Logon │
│ Information ┆ 10/6/2016 01:04:10 PM ┆ Microsoft-Windows-Security-Aud… ┆ 4624 ┆ Logon │
└─────────────┴───────────────────────┴─────────────────────────────────┴──────────┴───────────────┘
このツールは入力を担うinitializer, 加工を担うchainable functions, 出力を担うfinalizerの3種類の機能群からなります。
CLIからの実行時には、各機能間はハイフン(-)で明示的に区切る必要があります。
$ qsv {{INITIALIZER}} {{Arguments}} - {{CHAINABLE}} {{Arguments}} - {{FINALIZER}} {{Arguments}}
なぜこのような特殊な実装になっているかというと、Quilter-CSVの内部で使っているpolarsの遅延評価の恩恵を最大限に受けるためです。我慢してください
モチベーション
このツールを作成した理由として、ファストフォレンジックなどで大容量のログ分析をするときにいくつか困りごとがありました。
1つめに、私は通常ログ分析をするときは ripgrep や xsv, その他いくつかの標準コマンドを使うことが多いです。
この方法はざっとデータを確認するときには便利なのですが、定型化された作業をするのにはひどく向いていません。なぜなら、CSVとひとくちに言っても様々な呪われたフォーマットが混在しているため、処理するためにデバッグが非常に困難なシェル芸を披露しないといけません。
2つめに、メモリに到底乗り切らないようなサイズのファイルはxsvでは処理できません。実際に、以前1ファイル数百GBのイベントログを食わせたら死にました。
他にもCSVのセルのデータを正規表現で加工したいとかいろいろ。。
クイックスタート
インストール
pipでインストールする場合は下記コマンドでインストールします。
$ pip install qsv
WindowsとUbuntuならコンパイル済バイナリがあるのでReleasesから落としてください。
個人的にはこっちがおすすめだけど、NuitkaでコンパイルしてるからWindows Securityとかに怒られるかも。
気になる人はGitHub Workflowを見て自分でコンパイルしてもよし。
実行
CLI
前述のように、3種類の機能群を組み合わせて実行する必要があります。
chainable functionsは名前の通りいくつでもチェイン可能ですが、initializerとfinalizerは基本的に1つのみです。
$ qsv {{INITIALIZER}} {{Arguments}} - {{CHAINABLE}} {{Arguments}} - {{FINALIZER}} {{Arguments}}
例えば、Security.csvに対して下記の5つの操作をする場合は、次のようになります。
- 'EventId'列が4624である行をフィルタ
- 先頭5行のみにフィルタ
- 'RecordNumber', 'TimeCreated'列のみにフィルタ
- 'TimeCreated'列のタイムゾーンをUTCからAsia/Tokyoに変更
- テーブル形式で表示
$ qsv load Security.csv - isin EventId 4624 - head 5 - select RecordNumber,TimeCreated - changetz TimeCreated UTC Asia/Tokyo "%Y-%m-%d %H:%M:%S%.f" - showtable
shape: (5, 2)
┌──────────────┬────────────────────────────────┐
│ RecordNumber ┆ TimeCreated │
│ --- ┆ --- │
│ i64 ┆ datetime[μs, Asia/Tokyo] │
╞══════════════╪════════════════════════════════╡
│ 227443 ┆ 2016-10-06 10:47:21.955197 JST │
│ 227445 ┆ 2016-10-06 10:47:21.955197 JST │
│ 227449 ┆ 2016-10-06 10:47:21.955197 JST │
│ 227453 ┆ 2016-10-06 10:47:21.955197 JST │
│ 227511 ┆ 2016-10-06 10:49:00.937831 JST │
└──────────────┴────────────────────────────────┘
Quilt
CLIで紹介した機能をYAMLルールで定義し、一括で実行するキルトという機能もあります。
元ネタは学生のときに好きだった某ゲームの曲名です。
$ qsv quilt test.yaml Security.csv
Loaded Rules
┏━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ title ┃ description ┃ version ┃ author ┃
┡━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ test │ test filter │ 0.1.0 │ John Doe <john@example.com> │
└───────┴─────────────┴─────────┴─────────────────────────────┘
shape: (5, 2)
┌──────────────┬────────────────────────────────┐
│ RecordNumber ┆ TimeCreated │
│ --- ┆ --- │
│ i64 ┆ datetime[μs, Asia/Tokyo] │
╞══════════════╪════════════════════════════════╡
│ 227443 ┆ 2016-10-06 10:47:21.955197 JST │
│ 227445 ┆ 2016-10-06 10:47:21.955197 JST │
│ 227449 ┆ 2016-10-06 10:47:21.955197 JST │
│ 227453 ┆ 2016-10-06 10:47:21.955197 JST │
│ 227511 ┆ 2016-10-06 10:49:00.937831 JST │
└──────────────┴────────────────────────────────┘
ルールはこんな感じです。titleからauthorはなくても動作する。
rules配下に各機能名と引数(オプション)を記載してチェインさせます。
title: test
description: test filter
version: 0.1.0
author: John Doe <john@example.com>
rules:
load:
isin:
colname: EventId
values:
- 4624
head:
number: 5
select:
colnames:
- RecordNumber
- TimeCreated
changetz:
colname: TimeCreated
timezone_from: UTC
timezone_to: Asia/Tokyo
datetime_format: "%Y-%m-%d %H:%M:%S%.f"
showtable:
ヘルプ
下記コマンドでヘルプが見れます。
GitHubのREADMEには使用例もあるのでそっちも見てね。
$ qsv - --help
NAME
qsv
SYNOPSIS
qsv - COMMAND | VALUE
COMMANDS
COMMAND is one of the following:
changetz
[chainable] Changes the timezone of the specified date column.
contains
[chainable] Filters rows where the specified column matches the given regex.
dump
[finalizer] Outputs the processing results to a CSV file.
grep
[chainable] Treats all columns as strings and filters rows where any column matches the specified regex.
head
[chainable] Selects only the first N lines.
headers
[finalizer] Displays the column names of the data.
isin
[chainable] Filters rows containing the specified values.
load
[initializer] Loads the specified CSV files.
quilt
[quilter] Loads the specified quilt batch files.
renamecol
[chainable] Renames the specified column.
sed
[chainable] Replaces values using the specified regex.
select
[chainable] Selects only the specified columns.
show
[finalizer] Displays the processing results in a table format to standard output.
showquery
[finalizer] Displays the data processing query.
showtable
[finalizer] Outputs the processing results table to the standard output.
sort
[chainable] Sorts all rows by the specified column values.
stats
[finalizer] Displays the statistical information of the data.
tail
[chainable] Selects only the last N lines.
uniq
[chainable] Remove duplicate rows based on the specified column names.
VALUES
VALUE is one of the following:
df
おわりに
Quilter-CSVは開発中のツールです。
自分で使ってて不便な点があったら改良していく予定ですが、気になったことやバグなどあればドシドシissue, pull requestください。
お し ま い
Discussion