ファイルとディレクトリの再帰的リスト

$ find
.
./usr
./usr/local
./usr/local/share
./usr/local/share/man
./usr/local/share/man/man1
./usr/local/share/man/man1/hello.1
./usr/local/share/info
./usr/local/share/info/hello.info
./usr/local/share/info/dir
./usr/local/bin
./usr/local/bin/hello.exe

あれー?
findってディレクトリ名の末尾に/をデフォルトで付けてくれてなかったかな?(今更)
まあ、付いてない方が利用しやすいので、それがデフォルトなのはいいことだが。
今回の場合は付加されようがされまいが関係ないけど、
空ディレクトリがあった場合、それがファイルなのかディレクトリなのか区別ができない。

オプションとかアクションとかの指定で簡単にできるのかもしれないけれど、
調べるのが面倒くさいので適当にやってみる。

$ find -type f -print , -type d -printf %p/\\n
./
./usr/
./usr/local/
./usr/local/share/
./usr/local/share/man/
./usr/local/share/man/man1/
./usr/local/share/man/man1/hello.1
./usr/local/share/info/
./usr/local/share/info/hello.info
./usr/local/share/info/dir
./usr/local/bin/
./usr/local/bin/hello.exe

コマンドがちょっと長い感じもするけれど、やりたいことはできている。

考え方をちょっと変えてみる。

$ find -exec ls -dF {} \;
./
./usr/
...snip
./usr/local/bin/
./usr/local/bin/hello.exe*

やる前から分かってはいたけれど、やっぱり実行がもっさりする。
でもさっきよりキーを打つ量は少しだけ短くはなった。

上のやり方だと、ファイルのパーミションに実行可が付いてる場合に、
*がファイル名に付加されるのが邪魔っぽい。
そこで、lsのPOSIXオプション外になるけれど、

$ find -exec ls -dp {} \;
./
./usr/
...snip
./usr/local/bin/
./usr/local/bin/hello.exe

これで/は付くが*は付かなくなった。

同系統の考え方だが、
-exec command {} + アクションでパスリストを作成し、
lsにそのリストをいちどきに渡してみる。

$ find -exec ls -1dp {} +
./
./usr/
./usr/local/
./usr/local/bin/
./usr/local/bin/hello.exe
./usr/local/share/
./usr/local/share/info/
./usr/local/share/info/dir
./usr/local/share/info/hello.info
./usr/local/share/man/
./usr/local/share/man/man1/
./usr/local/share/man/man1/hello.1

この方法だと、パスリストの順序がソートされている。
また、-exec command ; アクションを使うよりも、実行は軽い感じがする。

で、結局、最初のファイルとディレクトリでアクションを分けて書くのが素直なような。
ソートされたパスリストが必要ならfindの出力をsortに引き渡す方向で。