awk で csv を処理する方法についての覚え書き

# awk で csv を処理する方法についての覚え書き

awk で csv を処理する方法について、少し調べたので、調べたことを共有します。
筆者の環境は 
- `OS:Ubuntu 24.04.1 LTS`
- `gawk:5.3.60` 
です。

## サンプルファイル

サンプルとして ceatec2024 の出展ブースの CSV からランダムに取り出したファイルを使います。

```ceatec2024.csv
location,booth
"8H457","北海道石狩市"
"3H091","内閣官房 デジタル田園都市国家構想実現会議事務局"
"5H250","名古屋大学「未来エレクトロニクス創成加速DII協働大学院プログラム」"
"3H096","独立行政法人情報処理推進機構"
"6H107-18","WISETIP DISPLAY CO., LTD."
"7H507","Lakeside Optoelectronic Technology Co., Ltd"
"6H107-20","EXCEL CELL ELECTRONIC CO., LTD."
"3H097","Connectivity Standards Alliance 日本支部"
"3H087","株式会社 MOYAI"
"5H400","UPBEAT TECHNOLOGY Co., Ltd."
"7H411","積水化学工業株式会社"
"8H543","株式会社ワークロボティクス"
"6H233","株式会社オースミ"
```

## 簡単な現在の状況

### CSV

CSV は広く使われているフォーマットです。仕様として RFC 4180 (2004年)がありますが、勘の良い読者ならこんな前世紀からありそうな仕様の日付がアテネオリンピックと同い年というのは少し不安を感じるでしょう。

[RFC 4180 - Common Format and MIME Type for Comma-Separated Values (CSV) Files](https://datatracker.ietf.org/doc/html/rfc4180)

CSV は非常にラフな使われ方をされていることでも知られています。

ここでは CSV をざっくりと
- ```,``` で分割された 1 行 1 データのファイル
- フィールドに ```,``` が入っていても可
- フィールドに `,` が入っている場合 `"` で囲われている
- ヘッダー可
として扱います。

### awk

2023 年にオリジナル作者の一人カーニハンが開発している One true awk が csv に対応しました。gawk でも 5.3.0 で対応しております。

もっとも以前から

- ```,``` で分割された 1 行 1 データのファイル
- フィールドに ```,``` が入っていない

といった申し分ないファイルなら、

```awk -F, '{print $0}' ./hoge.csv ```

で対応できていました。

フィールド内に```,```の入っているファイルでは gawk ならば FPAT を使い、正規表現でフィールドを抽出する方法で対応できますけれども、現在はより簡単な方法があるので、そちらを使います。

現在の Ubuntu ではまだバージョンが追いついていませんが、いずれ更新されるでしょう。

[Ubuntu – noble の gawk パッケージに関する詳細](https://packages.ubuntu.com/noble/gawk)

## --csv オプションを使う

CSV 用のオプションは `gawk -k` または `gawk --csv` で使用できます。
たったこれだけで改行とフィールド内の`,`に対応できます。

- CSV をヘッダー行を読み飛ばしつつ表示する

```sh
$ gawk --csv 'NR!=1 '{print $0}' ./ceatec2024.csv
```

`NR` は行番号を表す変数です。ヘッダーの行数に合わせて書き換えてください。

- 複数のディレクトリ内にある CSV ファイルのヘッダー行を読み飛ばして表示する

```sh
$ find . -name "*.csv" -exec gawk --csv 'FNR!=1 {print $0}' {} + 
```

`FNR` は各ファイルでの行番号を表す変数です。`NR`では指定したファイル全体の行番号になります(つまり、ヘッダーが表示されてしまう)。ヘッダーの行数に合わせて書き換えてください。

## おまけ・TSV(タブをセパレータとした CSV) を読む

```ceatec2024.tsv
location	booth
"8H457"	"北海道石狩市"
"3H091"	"内閣官房 デジタル田園都市国家構想実現会議事務局"
"5H250"	"名古屋大学「未来エレクトロニクス創成加速DII協働大学院プログラム」"
"3H096"	"独立行政法人情報処理推進機構"
"6H107-18"	"WISETIP DISPLAY CO., LTD."
"7H507"	"Lakeside Optoelectronic Technology Co., Ltd"
"6H107-20"	"EXCEL CELL ELECTRONIC CO., LTD."
"3H097"	"Connectivity Standards Alliance 日本支部"
"3H087"	"株式会社 MOYAI"
"5H400"	"UPBEAT TECHNOLOGY Co., Ltd."
"7H411"	"積水化学工業株式会社"
"8H543"	"株式会社ワークロボティクス"
"6H233"	"株式会社オースミ"
```
```sh
$ gawk -v FPAT="([^\\t]+)|(\"[^\"]+\")"  'NR!=1 {print $2}'  ./ceatec2024.tsv

"北海道石狩市"
"内閣官房 デジタル田園都市国家構想実現会議事務局"
"名古屋大学「未来エレクトロニクス創成加速DII協働大学院プログラム」"
"独立行政法人情報処理推進機構"
"WISETIP DISPLAY CO., LTD."
"Lakeside Optoelectronic Technology Co., Ltd"
"EXCEL CELL ELECTRONIC CO., LTD."
"Connectivity Standards Alliance 日本支部"
"株式会社 MOYAI"
"UPBEAT TECHNOLOGY Co., Ltd."
"積水化学工業株式会社"
"株式会社ワークロボティクス"
"株式会社オースミ"

```

上記では使わないといった FPAT ですが、このような使い方もあります。

## LINK

- [とほほのAWK入門 - とほほのWWW入門](https://www.tohoho-web.com/ex/awk.html)
    - 日本語で読める awk のリファレンスです。 awk を使うときはとりあえず開いています
- [CSVと親しくなるAWK術 | フューチャー技術ブログ](https://future-architect.github.io/articles/20210330/)
    - gawk に `--csv` オプションがなかった頃の記事。色々小技が載っていて楽しい