tree コマンドは文字コードによって出力が変わる

2022-03-24  /  Shell Script

たまたま気づいたのですが tree コマンドは端末の文字コードに応じて罫線の出力文字を変えていました。

デフォルトで出力

Mac で日本語で使っているので LANG=ja_JP.UTF-8 になっていました。

$ echo $LANG
ja_JP.UTF-8

このサイト(Hugo)の作業ディレクトリで実行してみます。

$ tree -L 1
.
├── _posts_
├── app
├── archetypes
├── config.toml
├── content
├── data
├── internal
├── layouts
├── posts.txt
├── public
├── resources
├── scripts
├── static
├── themes
└── work

13 directories, 2 files

ツリー構造を表す罫線にはマルチバイト文字が使用されています。

LANG=C を指定して確認

LANG=C を指定して実行してみます。

$ LANG=C tree -L 1
.
|-- _posts_
|-- app
|-- archetypes
|-- config.toml
|-- content
|-- data
|-- internal
|-- layouts
|-- posts.txt
|-- public
|-- resources
|-- scripts
|-- static
|-- themes
`-- work

13 directories, 2 files

ツリー構造を表す罫線には ASCII のみが利用されています。

実装

たぶんこの辺 だと思うんですが文字コードに応じて出力する罫線の定義が行われています。指定されているのは UTF8 の文字コードなのかな。

    { utf8,        “\342\224\202\302\240\302\240”, “\342\224\234\342\224\200\342\224\200”,
\342\224\224\342\224\200\342\224\200”, “\302\251”,
\342\216\247”, “ \342\216\251”, “ \342\216\250”, “ \342\216\252”,  “ {},

インデントを出力するのは この辺 のようですね。

      fprintf(outfile,"%s ",
	      dirs[i+1] ? (dirs[i]==1 ? linedraw->vert     : (Hflag? "   " : "   ") )
			: (dirs[i]==1 ? linedraw->vert_left:linedraw->corner));

ついでに知った便利オプション

使ってみるとこんな感じです。便利ですね。

p から始まるものを無視

$ tree -L 1 -I "p*"
.
├── _posts_
├── app
├── archetypes
├── config.toml
├── content
├── data
├── internal
├── layouts
├── resources
├── scripts
├── static
├── themes
└── work

12 directories, 1 files

JSON 形式で出力

# JSONで出力
$ tree -L 1 -J
[
  {"type":"directory","name":".","contents":[
    {"type":"directory","name":"_posts_"},
    {"type":"directory","name":"app"},
    {"type":"directory","name":"archetypes"},
    {"type":"file","name":"config.toml"},
    {"type":"directory","name":"content"},
    {"type":"directory","name":"data"},
    {"type":"directory","name":"internal"},
    {"type":"directory","name":"layouts"},
    {"type":"file","name":"posts.txt"},
    {"type":"directory","name":"public"},
    {"type":"directory","name":"resources"},
    {"type":"directory","name":"scripts"},
    {"type":"directory","name":"static"},
    {"type":"directory","name":"themes"},
    {"type":"directory","name":"work"}
  ]}
,
  {"type":"report","directories":13,"files":2}
]