どうやら私は数えられない。 /media
には3つのファイルがあると思います
$ tree /media
/media
├── foo
├── onex
└── zanna
3 directories, 0 files
ただし、ls -l
は12を検出します。
$ ls -l /media
total 12
drwxr-xr-x 2 root root 4096 Jul 31 20:57 foo
drwxrwxr-x 2 root root 4096 Jun 26 06:36 onex
drwxr-x---+ 2 root root 4096 Aug 7 21:17 zanna
そして、ls -la
を実行すると、上記に加えて.
と..
のみが取得されますが、カウントはtotal 20
です
説明は何ですか?
表示される12
はファイルの数ではなく、消費されたディスクブロックの数です。
info coreutils 'ls invocation'
から:
For each directory that is listed, preface the files with a line
`total BLOCKS', where BLOCKS is the total disk allocation for all
files in that directory. The block size currently defaults to 1024
bytes, but this can be overridden (*note Block size::). The
BLOCKS computed counts each hard link separately; this is arguably
a deficiency.
2つの追加ディレクトリ12
と20
をカウントしているため、ls -la
の代わりにls -l
を使用すると、合計は.
から..
になります。各(空の)ディレクトリに4つのディスクブロックを使用しているため、合計は3×4から5×4になります(おそらく、各ディレクトリにoneディスクブロック4096バイトを使用しています) ; info
ページが示すように、ユーティリティはディスク形式をチェックしませんが、特に指示がない限り、1024
のブロックサイズを想定します。
単にファイルの数を取得したい場合は、次のようなものを試してみてください
ls | wc -l
ser4556274は既に回答済み thewhy私の答えは、howの追加情報を提供して、ファイルを適切にカウントすることだけです。
Unixコミュニティでは、一般的なコンセンサスは、 ls
の出力の解析は非常に悪い考えです です。ファイル名には制御文字または隠し文字が含まれる可能性があるためです。たとえば、ファイル名に改行文字があるため、ls | wc -l
にls
(含まれている)の出力に5行あることが示されていますが、実際にはディレクトリに4つのファイルしかない。
$> touch FILE$'\n'NAME
$> ls
file1.txt file2.txt file3.txt FILE?NAME
$> ls | wc -l
5
find
コマンドは、通常ファイル名の解析に使用されますが、ここでは inode番号 を出力することで役立ちます。ディレクトリでもファイルでも、一意のiノード番号は1つだけです。したがって、-printf "%i\n"
を使用し、.
を介して-not -name "."
を除外すると、ファイルの正確なカウントを取得できます。 (-maxdepth 1
を使用してサブディレクトリへの再帰的な下降を防ぐことに注意してください)
$> find -maxdepth 1 -not -name "." -print
./file2.txt
./file1.txt
./FILE?NAME
./file3.txt
$> find -maxdepth 1 -not -name "." -printf "%i\n" | wc -l
4
シンプル、迅速、そしてほとんどポータブルな方法:
$ set -- *
$ echo $#
228
set
コマンドは、シェルの位置パラメーター($<INTEGER>
のようにecho $1
変数)を設定するために使用されます。これは、配列不足の/bin/sh
制限を回避するためによく使用されます。追加のチェックを実行するバージョンは、Unix&Linuxの Gille's answer overにあります。
bash
などの配列をサポートするシェルでは、次を使用できます。
items=( dir/* )
echo ${#items[@]}
コメント内のスチールドライバー によって提案されたとおり。
find
およびglobstarを使用したwc
メソッドと同様のトリックをstat
とともに使用して、行ごとにiノード番号をカウントできます。
$> LC_ALL=C stat ./* --printf "%i\n" | wc -l
4
別の方法は、for
ループでワイルドカードを使用することです。 (このテストでは、別のディレクトリを使用して、このアプローチがサブディレクトリに下降するかどうかをテストします。サブディレクトリには下降しません。16は、~/bin
の検証済みアイテム数です)
$> count=0; for item in ~/bin/* ; do count=$(($count+1)) ; echo $count ; done | tail -n 1
16
Pythonは、os.listdir()
関数(再帰的ではなく、引数として指定されたディレクトリ内の項目のみをリストします)を指定したリストの長さを出力することで、問題のあるファイル名にも対処できます。
$> python -c "import os ; print os.listdir('.')"
['file2.txt', 'file1.txt', 'FILE\nNAME', 'file3.txt']
$> python -c "import os ; print(len(os.listdir('.')))"
4