macOSのターミナルでCSV表示
macOSのターミナルでCSVを整形して表示できないかと探していたところ、csvkitやcsvlookのアプリケーションをインストールして実現できるようです。しかしもっと簡単な方法がありました。columnというバンドルされているコマンドを使うことで、CSVを整形して表示させることが可能です。Shift-JISでエンコードされたCSVはそのままだと文字化けしてしまいますが、これはiconvでUTF8へエンコードしてからcolumnへ標準出力して渡してあげればクリアできる問題です。
columnを使ってターミナルでCSVを整形して表示
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 をご覧ください。
シェルスクリプトにして使いやすいようにする
最初に紹介したワンライナーのコマンドを少し改造して、シェルスクリプトにしてみました。
#!/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で配置し、実行権限を与えたとします。次のようにして使うことが可能になります。
$ 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ファイル名>で転置モードに切り替わります。
#!/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などのエンコードにも対応しています。