1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

サッと使いたいawkコマンド改めqコマンド

Last updated at Posted at 2022-09-21

始めに

今まで数GBのようなある程度大きいCSVを処理したい時には、awkを使うことがそれなりにあった
理想的には、スプレッドシートで済ましたいけど、結構重くなって、場合によっては処理できないこともある

なので、頻度はそこまで多くないけど、必要な時にサッと使いたい機能をメモしておこう

# 例. 空文字でない該当列の値を出力
cat file.csv | awk 'BEGIN{FS=","} {if($6!=""&&$7!=""){print $6,$7}}' | less

と思ったのだけど、awkは複雑なCSVを厳密にパースするのには向いていない

gawkの開発は「完全を目指すのではなく9割をサクサクこなし、フィールドに改行を含むようなCSVファイルは専用のツールで処理すれば良い」という思想で進められました。

上記制限を許容した上で利用する分には良いけれど、、と思っていたところ、他にも色々手段がある

紹介されている中で最も定番ぽい印象を受けた qコマンド について、調べたことを簡単にメモしておく

前提

$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.15.7
BuildVersion:	19H15

$ q -v
q version 3.1.6
Python: 3.9.7 (default, Oct 18 2021, 00:59:13) // [Clang 13.0.0 ]
Copyright (C) 2012-2021 Harel Ben-Attia (harelba@gmail.com, @harelba on twitter)
http://harelba.github.io/q/

まずはインストールしましょう

使い方

基本的には、以下のフォーマットで使っている

$ nkf -w file.csv | q -H -d, -O -T -q ./test.sql | less

# 補足
# 文字コード変換する必要がなければ、`nkf` する必要なし
# ヘッダーがない場合は、`-H` をなくして SQL のカラムは c1, c2, ... を使う
# SQL を直接指定する場合は、`-q ./test.sql` をなくす(例. "select * from -")

入力

  • 基本的には、qコマンド に入力する前に別ツールで文字コード変換している
    • 文字コード変換用のオプションがある
    • けれど、手元で試した時に上手く読み込めなかった(詳細は後述)

オプション

  • ヘッダー読み込み
    • -H
  • 区切り文字指定
    • カンマ: -d,
    • タブ: -t
  • ヘッダー出力
    • -O
      • ヘッダー変換したい場合は、上記を指定した上で AS 句を使う
  • タブ区切り出力
    • -T
  • SQLファイル実行
    • -q [ファイルパス]
      • ファイルに記載するSQLはクォートで囲む必要なし
  • 文字コード指定
    • -e data-encoding
    • -Q query-encoding
    • -E output-encoding

SQL

  • SQLite3準拠しているとのこと
    • いくつか制限がある
      • サブクエリをfromに置けないとか(whereには書ける)
    • group by, having, join, ...
    • 関数 count, sum, substr, ...
  • from 指定
    • 標準入力: -
    • ファイル: [ファイルパス]
  • カラム名
    • ヘッダー行あれば(-H 指定) 、ヘッダー名
    • なければ、c1, c2, ...

補足

CSV のパース

いくつかバリエーションを試したが、特に問題なし

# フィールド内にカンマを含むケース
$ echo 'aaa,"bbb,ccc",ddd' | q -d, "select c2 from -"
=>
"bbb,ccc"

# フィールド内に改行を含むケース
$ echo -e "aaa,\"bbb\nccc\",ddd" | q -d, "select c2 from -"
=>
"bbb
ccc"

# フィールド内にダブルクオートそのものを含むケース
$ echo 'a,"b""c",d' | q -d, "select c2 from -"
=>
"b""c"

# フィールド内にエスケープされていない二重引用符を含むケース
# ※ 不正CSV(RFC 4180 に違反)
$ echo 'a,b"c,d' | q -d, "select c2 from -"
=>
"b""c"

文字コードの変換

Shift_JIS の CSV を読み込もうとしたらエラー
※ 日本語を含む 250MB 程のファイル

$ nkf -guess file.csv
Shift_JIS

$ cat file.csv | q -H -d, -e Shift_JIS -Q UTF-8 -E UTF-8 "select c1, count(1) from -" | less
=>
Could not parse the input. Please make sure to set the proper -w input-wrapping parameter for your input, and that you use the proper input encoding (-e). Error: 'utf-8' codec can't decode byte 0xca in position 293: invalid continuation byte

他のツールだと問題なく読み込める

# 例. Ruby
CSV.read('file.csv', encoding: 'Shift_JIS:UTF-8')

日本語を含むファイルの文字コード変換は、他ツールを使った方が無難?

$ nkf -w file.csv | q -H -d, "select カラム1 from -" | less

終わりに

簡単に使い方を調べて、qコマンドの便利さを理解できたので、実際に使っていこうと思う(データ量が多い場合には、Athena を使えば事足りそう)

類似ツールは Go が多いようで早そうだけど、現状特に課題感はなくて当分は良さそう

後、今回のような些細な記事一つ取っても、改めて視野を広げて取り組まないといけないなと

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?