[Linux] ディレクトリをツリー状に表示する - tree

今回は以下のようにディレクトリやファイルをツリー状に表示してくれるtreeコマンドです。

$ tree .
.
├── LICENSE.txt
├── README.md
├── bin
│   └── gpwd.js
├── coverage
│   ├── clover.xml
│   ├── coverage-final.json
│   └── lcov.info
├── index.js
├── package-lock.json
├── package.json
└── test
    └── genPassword.test.js

インストール

標準では含まれていない場合がありますので、yumやdnfなどでインストールします。macOSの場合もbrewで一発です。

$ sudo yum install tree

バージョン情報を確認すると日本人の方も参加されていらっしゃるっぽいですね。

$ tree --version
tree v1.6.0 (c) 1996 - 2011 by Steve Baker, Thomas Moore, Francesc Rocher, Kyosuke Tokoro

利用方法

オプション未指定

何もオプションを指定しないと、カレントディレクトリを起点としたツリーを表示してくれます。以下の2つは同じ意味ですね。

$ tree
$ tree .

ディレクトリのみ表示

-dオプションを付けるとディレクトリだけが対象となります。

$ tree -d
.
├── check
├── file
├── image
├── slide
└── syllabus

ディレクトリを先に表示する

--dirsfirstオプションでディレクトリを先に、ファイルをそのあとに表示できます。

$ tree -N --dirsfirst
.
├── check
│   └── check_1st.pdf
├── file
│   ├── TM_20191021.zip
│   └── TM_20191028.zip
├── image
│   ├── usage_login1.png
│   ├── usage_login2.png
│   ├── usage_login3.png
│   └── usage_login4.png
├── slide
│   ├── 20191007_AM.pdf
│   └── 20191118_PM.pdf
├── syllabus
│   ├── syllabus_AM.pdf
│   └── syllabus_PM.pdf
├── Apacheの使い方.md
├── CSSのはじめ方.md
├── GitHubの始め方.md
├── Gitの始め方.md
├── HTMLのはじめ方.md
├── Home.md
└── 授業中に追加で行った設定.md

ディレクトリの階層を指定する

猛烈に深い階層まで表示せずとも良い場合は、どの程度潜るか、-Lオプションで階層を指定することができます。以下の例のように1だと最初の階層のみを対象とします。

$ tree -N -L 1
.
├── Home.md
├── check
├── file
├── image
├── slide
├── syllabus
└── 授業中に追加で行った設定.md

ファイルやディレクトリをソートする

ファイルの更新時間や名前でソートできます。デフォルトは「ファイル名」です。

オプション 内容
-r ファイル名(逆順)
-t ファイルの更新時間

ファイルやディレクトリの詳細情報を表示

以下のようなオプションを付けることで、lsコマンドのような情報をあわせて表示することができます。

オプション 内容
-p パーミション。ls -lと同様の表示
-u 所有者
-g グループ
-s ファイルサイズ (byte)
-h ファイルサイズを人間が見てわかりやすく表示(K,M,Gなどが付与される)
-D ファイルの更新時刻

まるっと付けてみました。ファイルやディレクトリの横に括弧が登場しその中にひたすら情報が詰め込まれるようです。

$ tree -p -u -g -s -h -D
.
├── [drwxr-xr-x katsube  staff    2.2K Aug 29 18:33]  image/
│   ├── [-rw-r--r-- katsube  staff     96K Dec  2  2018]  usage_login1.png
│   ├── [-rw-r--r-- katsube  staff     89K Dec  2  2018]  usage_login2.png
│   ├── [-rw-r--r-- katsube  staff     46K Dec  2  2018]  usage_login3.png
│   └── [-rw-r--r-- katsube  staff     36K Dec  2  2018]  usage_login4.png
()

ファイルをパターンで絞り込む

「一致する」ファイルのみ表示

以下の例では拡張子が.pdfのファイルのみ対象とします。ディレクトリはすべて含まれます。

$ tree -P '*.pdf'
.
├── check
│   └── check_1st.pdf
├── file
├── image
├── slide
│   ├── 20191007_AM.pdf
│   └── 20191118_PM.pdf
└── syllabus
    ├── syllabus_AM.pdf
    └── syllabus_PM.pdf

-Pオプションに続いて「文字列」を渡す点に注意してください。シングルコーテーションなどの引用符で囲わないと、Bashなどのシェルがコマンドへ値を渡す前に展開してしまうからですね。

実際に引用符で囲わないと異なる動作になります。

$ tree -P *.pdf
zsh: no matches found: *.pdf

「一致しない」ファイルのみ表示

-Pと逆のパターンは-Iオプションで可能です。

$ tree -I '*.pdf'
.
├── Home.md
├── check
├── file
│   ├── TM_20191021.zip
│   └── TM_20191028.zip
├── image
│   ├── usage_login1.png
│   ├── usage_login2.png
│   ├── usage_login3.png
├── slide
└── syllabus

その他

日本語のファイル名を表示

通常日本語のような多バイト文字はエスケープされて表示されるため、パッと見ると文字化けしているような状態になります。

$ tree .
.
├── Apache?\201?使?\201\204?\226?.md
├── CSS?\201??\201??\201\227?\202\231?\202\201?\226?.md
├── GitHub?\201??\213?\202\201?\226?.md

-Nオプションを付けることで、エスケープをせずそのまま表示してくれます。

$ tree -N .
.
├── Apacheの使い方.md
├── CSSのはじめ方.md
├── GitHubの始め方.md

以下のサイトを参考にさせていただきました。
http://qno.oops.jp/wp/macintosh/232.html

lsでは出来ない?

ディレクトリの構造を調べたい場合、ls -Rなどでも一覧表示することは可能ですが、パッと見どのような構造になっているか直感的に判別することは容易ではありません。

実際に実行すると以下のような形で、再帰的に表示してくれますが、複雑な構造だと手に負えなくなってきます。

$ ls -R
README.md          bin/               coverage/          index.js           package-lock.json  package.json       test/

./bin:
gpwd.js*

./coverage:
clover.xml           coverage-final.json  lcov-report/         lcov.info

./coverage/lcov-report:
base.css               genPassword.js.html    index.js.html          prettify.js            sorter.js
block-navigation.js    index.html             prettify.css           sort-arrow-sprite.png

./test:
genPassword.test.js

参考ページ