lsコマンドはコマンドライン操作を覚える時に真っ先に覚えるコマンドだと思います。
簡単なコマンドなので改めてマニュアルを読むことはあまりないかと思いますが ちょっと気になって読んでみてコラム表示などについてあまり良く知らなかったので メモしておこうと思います。
lsにはGNU版、BSD版がありますが、確認した限りでは以下のことは共通です。
lsのターミナルへの通常表示
ターミナル上でlsコマンドを打つと、
$ ls
Applications Documents Dropbox Movies Pictures tmp
Desktop Downloads Library Music Public usr
こんな感じで横にいくつか列(column)を作って最小行で表示できる様(multi-column表示)に 表示してくれます。
この時、ディレクトリやファイルはソートされた状態で表示されますが 表示順は左の列から始まり下に行き、次の列に移り…という順序になっています。
ソートの方法はシステム設定($LANG等の値)によります。
もしくは-t(時間ソート)、-r(逆反転)などのlsのオプションでソートの方法を指定することも出来ます。
ls -x
-xを使うと表示順がまず最初の行を埋め(右に行く方向で進む)、次の行へ、という順番になります。
$ ls -x
Applications Desktop Documents Downloads Dropbox Library Movies Music Pictures Public
tmp usr
こんな感じに。この時、-x無しのときとは違い
最初の行から埋めていく形になるためか、最初の行で表示できるだけ表示します。
ファイルやパイプに繋いだ時の表示
ターミナルに表示する際には複数列の表示でコンパクトに表示してくれますが、 ファイルに書き出すときやパイプなどに繋いだ時は 各ファイル、ディレクトリ間がスペースではなく全て改行コードで埋められます。
$ ls | less
Applications
Desktop
Documents
Downloads
Dropbox
Library
Movies
Music
Pictures
Public
tmp
usr
lines 1-12/12 (END)
これによってスペース名が入っているファイル名などがある場合でも、
for文とかに渡す際にIFSを$'\n'(改行)を指定することでちゃんと回す事ができます。
この様にターミナル表示(標準出力時)とファイル等への書き込み時に違う表示にする様なプログラムは結構あります。
lsの場合もこれ以外にもファイルなどへの書き込み時にはカラー表示等も省かれます。
lsのソースコード(C言語)を読んでないので実際の実装は知りませんが
シェルスクリプトでも同じ様な事が出来て、
簡単な例は下にあります。
ファイルやパイプに繋いだ時も複数列表示にしたい時
-Cオプションを使います。
$ ls -C | less
Applications Downloads Movies Public
Desktop Dropbox Music tmp
Documents Library Pictures usr
lines 1-3/3 (END)
この時、ファイルに書き出してみると分かりますが 各ファイルやディレクトリ間はタブで埋められています。
なので直接lessで見ると崩れてしまいますが、
$ ls -C | cat
Applications Downloads Movies Public
Desktop Dropbox Music tmp
Documents Library Pictures usr
みたいな感じでcatで見ると(もしくは一度ファイルに吐き出してそれをcatすると)
きれいに揃って見えます。
ただし最初のlsと比べて列の数が少ない(行が多い)ことに気付くと思います。
これは、表示する際にlsは$COLUMNSというターミナルの横幅の文字数を見ていて、
ターミナル表示だと実際に表示しているターミナルのもの(この時は134)、
ファイルやパイプに流す際にはデフォルト80を使って表示を調整しているためです。
$COLUMNSはターミナルの大きさによって自動的に設定される環境変数ですが
これを変更してあげればlsの表示を替えられます。
ただ直接変更すると色々不具合があるので
$ COLUMNS=100 ls
みたいに実行時だけ変更する様にするべきです。
また、この様に設定するとファイルやパイプに繋いだときでもその$COLUMNSの値を使ってくれます。
なのでターミナル表示と同じにしたければ
$ COLUMNS=$COLUMNS ls -C | cat
Applications Documents Dropbox Movies Pictures tmp
Desktop Downloads Library Music Public usr
みたいにすればターミナルのコラム数を使って同じ表示を出せます。
ターミナル表示で各行1ファイル/ディレクトリ表示したい時
逆に通常のターミナル表示で各行一つずつ表示したい時は
$ COLUMNS=1 ls
Applications
Desktop
Documents
Downloads
Dropbox
Library
Movies
Music
Pictures
Public
tmp
usr
みたいな感じにCOLUMNSを1にしてあげれば一つの名前で一杯になるので全て違う行に表示する事が出来ます。
column
ちなみにこの様なlsのmulti-columnな表示ですが、
columnというコマンドを使うと同じ様に整形された表示に出来ます。
1 2 3 4 5 6 7 8 9 10 11 12 | |
なファイルを用意して、
$ column test.txt
Applications Documents Dropbox Movies Pictures tmp
Desktop Downloads Library Music Public usr
とすればlsと同じ結果に。
$ cat test.txt | column
Applications Documents Dropbox Movies Pictures tmp
Desktop Downloads Library Music Public usr
みたいな感じでパイプで受けてとる事もできます。
columnにはlsと同様、行を埋めていく-xオプションがあります。
また、横幅はls同様$COLUMNSの値で決まり、ファイルへの出力等の場合にはデフォルト80になりますが、
これを変更するには-c 50の様に-cを使う事が出来ます。
lsの時の様にその場だけでCOLUMNSの値を変更することでも出来ますがより簡単に書けます。
当然ですがcolumnの場合はlsと違い特別なオプションをつけなくてもファイルへの出力でもmulti-columnな表示になります。
