macOSのターミナルでCSV表示

macOSのターミナルでCSVを整形して表示できないかと探していたところ、csvkitcsvlookのアプリケーションをインストールして実現できるようです。しかしもっと簡単な方法がありました。columnというバンドルされているコマンドを使うことで、CSVを整形して表示させることが可能です。Shift-JISでエンコードされたCSVはそのままだと文字化けしてしまいますが、これはiconvでUTF8へエンコードしてからcolumnへ標準出力して渡してあげればクリアできる問題です。

columnを使ってターミナルでCSVを整形して表示

zsh
iconv -f SJIS -t UTF8 test.csv | column -t -s"," | less -#2 -N -S

コマンドを見ていただければ、これ以上の説明はいらないでしょう。ビューワーはお好みのものをお使いください。ここではlessを使用しました。

lessの操作

いちおう、lessの基本操作を記述しておきます。

操作実行結果備考
u or w半ページ戻る
d半ページ進む
g先頭へ飛ぶ
G最終行へ飛ぶ
n検索
Fファイルの更新を監視して
リアルタイムで反映
ctrl+cで終了
q終了

さらに詳しくは $ man less をご覧ください。

シェルスクリプトにして使いやすいようにする

最初に紹介したワンライナーのコマンドを少し改造して、シェルスクリプトにしてみました。

bash
#!/bin/bash

if [[ $# -lt 1 ]]; then
  echo "Usage: csv <file>"
  exit 1
fi

# nkfを使用してファイルのエンコーディングを判定
encoding=$(nkf --guess "$1" | cut -d " " -f 1)

# 判定されたエンコーディングがUTF-8なら、iconvをスキップ
if [[ $encoding == "UTF-8" ]]; then
  cat "$1" | column -t -s","
else
  # 判定されたエンコーディングを使用してiconvを実行
  iconv -f "$encoding" -t UTF8 "$1" | column -t -s","
fi

ファイルのエンコードを自動検出するために、nkfコマンドを使いますのでない場合はインストールしておきます。

このシェルスクリプトをPATHを通した~/binなどに、ファイル名csvで配置し、実行権限を与えたとします。次のようにして使うことが可能になります。

zsh
$ csv <CSVファイル名>

実行例

less -#2 -N -S alias less='less -SNIK'でaliasに登録しておくと便利です。次のようにしてCSVファイルを表示できます。
csv plants.csv | less

CSVファイルがShift JISだろうが、UTF-8だろうが、自動でエンコードして整形表示されます。めちゃ便利になりました!

テーブルの縦横を転置する

さらにCSVファイルを縦横入れ替えて転置する機能を、先ほどのシェルスクリプトに実装してみました。csv -t <CSVファイル名>で転置モードに切り替わります。

zsh
#!/bin/bash

# 転置オプションの初期値を設定
transpose=0

# オプション解析 (-t で転置を行う)
while getopts ":t" opt; do
  case ${opt} in
    t )
      transpose=1
      ;;
    \? )
      echo "Invalid option: $OPTARG" 1>&2
      ;;
  esac
done
shift $((OPTIND -1))

if [[ $# -lt 1 ]]; then
  echo "Usage: csv <file>"
  exit 1
fi

# CSVファイルを転置して整形する関数
transpose_and_format() {
    awk -F, '{
        for (i=1; i<=NF; i++) a[i,NR]=$i
    } END {
        for (i=1; i<=NF; i++) {
            for (j=1; j<=NR; j++) printf "%s,", a[i,j];
            print ""
        }
    }' | sed 's/,$//' | column -t -s,
}

encoding=$(nkf --guess "$1" | cut -d " " -f 1)

if [[ $transpose -eq 1 ]]; then
  if [[ $encoding == "UTF-8" ]]; then
    cat "$1" | transpose_and_format
  else
    iconv -f "$encoding" -t UTF8 "$1" | transpose_and_format
  fi

else
  if [[ $encoding == "UTF-8" ]]; then
    cat "$1" | column -t -s","
  else
    iconv -f "$encoding" -t UTF8 "$1" | column -t -s","
  fi

fi

実行例

$ csv plants.csv | less を実行してみると下図のように転置されて表示されます。もちろんShift-JISなどのエンコードにも対応しています。

関連記事

最後までご覧いただきありがとうございます!

▼ 記事に関するご質問やお仕事のご相談は以下よりお願いいたします。
お問い合わせフォーム

関連記事