web-dev-qa-db-ja.com

ディレクトリ内のファイル数をカウントする最良の方法は何ですか?

lsの出力を解析すると、ファンキーな文字(スペース、\n、...)、ディレクトリ内のファイル数を知るための最良の方法は何ですか?

私は通常、この解析を回避するためにfindに依存していますが、同様にfind mydir | wc -lは同じ理由で壊れます。

私は現在Solarisで作業していますが、さまざまなユニックスやさまざまなシェル間で可能な限り移植性のある答えを探しています。

11
rahmu

このトリックはどうですか?

find . -maxdepth 1 -exec echo \; | wc -l

findおよびwcと同じくらい移植可能です。

15
rozcietrzewiacz

Bashを使用し、外部ユーティリティもループもなし:

_shopt -s dotglob
files=(*)
echo ${#files[@]}
_

Kshでは、_shopt -s dotglob_をFIGNORE=.?(.)に置き換えます。 zshでは、それを_setopt glob_dots_に置き換えるか、shopt呼び出しを削除してfiles=(*(D))を使用します。 (または、ドットファイルを含めたくない場合は、単に行を削除してください。)可搬性があり、ドットファイルを気にしない場合:

_set -- *
echo $#
_

ドットファイルを含めたい場合:

_set -- *
if [ -e "$1" ]; then c=$#; else c=0; fi
set .[!.]*
if [ -e "$1" ]; then c=$((c+$#)); fi
set ..?*
if [ -e "$1" ]; then c=$((c+$#)); fi
echo $c
_
11
enzotib
find . ! -name . -Prune -print | grep -c /

80年代以降のシステムにかなり移植可能であるべきです。

現在のディレクトリの...を除くすべてのディレクトリエントリがカウントされます。

サブディレクトリ内のファイルもカウントするには:

find .//. ! -name . | grep -c //

-Pruneが必要ないため、Unix V6(1975)にも移植可能である必要があります)

8

試してください:

ls -b1A | wc -l

-bには印刷できない文字が含まれ、-A...を除くすべてのファイルと、1行に1つ(パイプのデフォルトですが、明示するのが適切です) )。

高レベルのスクリプト言語を含める限り、Pythonのワンライナーは次のとおりです。

python -c 'import os; print len(os.listdir(os.sep))'

または完全な「検索」:

python -c 'import os; print len([j for i in os.walk(os.sep) for j in i[1]+i[2]])'
6
Arcege

Yocはこのような構造を使用できます。

I=0; for i in * ; do ((I++)); done ; echo $I

しかし、私は恐れています、あなたはArgument list too long.ディレクトリにファイルが多すぎる場合。しかし、100億ファイルのディレクトリでテストしたところ、問題なく動作しました。

1
rush

比較的移植性のあるPerlを検討しましたか?

何かのようなもの:

use File::Find;

$counter = 0;

sub wanted { 
  -f && ++$counter
}

find(\&wanted, @directories_to_search);
print "$counter\n";
1
cjc

Perlワンライナー付き(読みやすくするために再フォーマット):

Perl -e 'opendir($dh, ".");
         while ( readdir($dh) ) {$count++};
         closedir $dh;
         print "$count\n";'

または

Perl -e 'opendir($dh, ".");
         @files = readdir($dh);
         closedir $dh;
         print $#files+1,"\n";'

2番目のバージョンでは、Perlgrepなどの配列を変更するmap関数を使用できます。見る perldoc -f readdirは、grepを使用した例です。

0
cas

これを試してください=>使用 ls -i(ノード番号用)および-F(ディレクトリ名に「/」を追加)オプションを使用します。

ls -ilF | egrep -v '/' | wc -l
0
Saumil

findベースの回答 Stéphaneによって提案 に加えて、以下はlsに基づくPOSIX準拠の回答です。

ls -qf | tail -n +3 | wc -l
0
xhienne

私がいつも使用していて問題がなかった最も単純なバージョンは次のとおりです:ls -b1 | wc -l

0
Peter