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


11

ls一部のファンキーな文字(スペース\n、...)で壊れる可能性があるため、の出力の解析が危険な場合、ディレクトリ内のファイル数を知るための最良の方法は何ですか?

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

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


3
重複しているのかわかりませんが、何か不足していますか?
rahmu 2014年

1
これは重複している可能性がありますが、示された質問のものではありません。find再帰的にファイルのあなたは数(使用でしょう-maxdepth 1あなたはそれをしたくない場合は。find mydir -maxdepth 1 -type f -printf \\n | wc -l彼らは最初の場所に印刷されることはありませんように、ファイル名に特殊文字を処理する必要があります。
Anthonの

回答:


16

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

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

以下のような携帯型として、findそしてwc


5
これは機能しません(n+1私のDebianシステムでファイルを表示します)。また、通常のファイルをフィルタリングしません。
クリスダウン

4
私は一般的な例を挙げただけです。それは機能しますが、どのように機能するかは、findコマンドを特定のニーズにどのように適合させるかによって異なります。はい、これには、を含むすべてのディレクトリが含まれ.ます(そのため、結果がと表示されることがありますn+1)。
rozcietrzewiacz

私はこのトリックがとても賢いのが好きです。しかし、それを行う簡単な簡単な方法がないことに驚いています!
rahmu

3
@ChrisDown OPは通常のファイルのフィルタリングを指定せず、ディレクトリ内のファイル数を要求します。n + 1の問題を取り除くには、を使用しfind . -maxdepth 1 ! -name . -exec echo \; | wc -lます。の一部の古いバージョンにはfindありません-not
Arcege

3
これ-maxdepthは標準ではないことに注意してください(GNU拡張は現在、他のいくつかの実装でもサポートされています)。
ステファンChazelas

11

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

2
最初の例は、が有効でない1場合に空のディレクトリを出力しnullglobます。zshではa=(*(DN));echo ${#a}Nnullglob)修飾子を使用しても、空のディレクトリのエラーは発生しません。
nisetama 2016年

8
find . ! -name . -prune -print | grep -c /

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

それは除いて、すべてのディレクトリエントリをカウント.し、..カレントディレクトリに。

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

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

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


このページでの唯一のポータブルな回答ではないにしても、ポータブルな回答の1つです。
xhienne

この回答は、現在のディレクトリ(find dirname ! -name dirname -prune -print)以外のディレクトリでもうまく機能することがわかったので、昨日賛成しました。私はそれ以来、grep -c /代わりに使用する特定の理由があるかどうか疑問に思っていますwc -l(おそらくより一般的に使用されます)。
Anthony Geoghegan

1
find dirname ! -name dirnameという名前のディレクトリが他にある場合は機能しませんdirname。使用することをお勧めしますfind dirname/. ! -name .wc -l行数を数えます。改行文字はファイル名と同様に有効であるため、ファイル名は数行で構成できます。
ステファンChazelas

6

試してください:

ls -b1A | wc -l

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

高水準のスクリプト言語を含める限り、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]])'

1

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

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

しかし、私は恐れていArgument list too long.ます、ディレクトリにファイルが多すぎる場合のように、エラーを引き起こす可能性があります。ただし、100億ファイルのディレクトリでテストしたところ、問題なく動作しました。


3
シェルがでそれらを展開するように構成されていない限り、これは隠しファイルに対しても機能しません*
Lekensteyn

gnu find . -maxdepth 1 -type f | wc -l
Nikhil

4
@Rush:このコマンドで「arg list too long」が発生することはありません。それはだけでそう決して(外部コマンドを使用して起こりませんfor
enzotib

1

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

何かのようなもの:

use File::Find;

$counter = 0;

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

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

0

これを試してください=> lsを-i(ノード番号の場合)&-F(ディレクトリ名に '/'を付加して)オプションを付けて使用します。

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

0

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番目のバージョンとperl同じように、grepまたはmap2番目のバージョンで配列を変更する関数を使用できます。をperldoc -f readdir使用した例については、を参照してくださいgrep


0

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


ファイル名にa \nまたはその他のファンキーな文字が含まれている場合、問題が発生する可能性があります(そう、特定のuniceではこれを許可しています)。
rahmu 2017

1
私は自分の回答を投稿する前にこれを明示的に試しましたが、問題はありませんでした。nautilusファイルマネージャを使用してファイル名を変更し、\ nを含めてみました。
Peter

そうですね。これを最初にテストしたときに何をしたかわかりません。もう一度試して、私の答えを更新しました。
ピーター

いいえ、コマンドは問題ありませんが、同様の解決策がすでにあり、隠しファイルはカウントされません。
xhienne

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.