コマンドラインを使用してディレクトリ内のファイルの数を取得するにはどうすればよいですか?


193

多数のファイルがあるディレクトリがあります。lsカウントを提供するスイッチが表示されません。ファイル数を取得するためのコマンドラインマジックはありますか?



tree . | tailまたはtree -a . | tail、隠しファイル/ディレクトリを含めるには、それtreeが必要な場合は再帰的です。
コーディチャン

回答:


239

「ファイル」の広範な定義を使用する

ls | wc -l

(隠しファイルはカウントせず、ファイル名に改行文字が含まれないと想定していることに注意してください)。

隠しファイルを含める(除くために...)と改行文字の問題を避けるため、標準的な方法は次のとおりです。

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

または再帰的に:

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

23
wc「単語数」プログラムです。-lスイッチは、行をカウントすることになります。この場合、からの出力の行をカウントしていますls。これは、常に特定のディレクトリのファイル数を取得するように教えられた方法です。
サンディ

20
ノート追加してくださいlsませls -1出力がパイプである場合を。
レスマナ

6
ディレクトリ内のすべてを取得するわけではありません-ドットファイルを見逃し、余分な行もいくつか収集します。空のディレクトリでも1行が返されます。を呼び出すとls -la、ディレクトリに3行が表示されます。あなたは欲しいls -lA | wc -lスキップする...エントリを。ただし、まだ1つずれています。

1
空のディレクトリは私のために0を返す
ジェームズ・ロス

2
名前に改行を含むファイルを二重にカウントしない修正アプローチは、次のようになりますls -q | wc -l
godlygeek

31

ファイルの狭い定義の場合:

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

もちろん、-maxdepth 1ファイルを再帰的にカウントするためのを省略できます(または、目的の最大検索深度に合わせて調整します)。
user7089 14

1
名前に改行が含まれるファイルがある場合、この方法では誤って2回カウントされます。
godlygeek

7
:修正されたアプローチは、その名前に改行を持つ二重カウントファイルは、このなりませんfind -maxdepth 1 -type f -printf "\n" | wc -l
godlygeek

+1隠しファイルを許可し、ディレクトリを無視します
Michael Durrant

14
ls -1 | wc -l

...

$ ls --help | grep -- '  -1'
    -1                         list one file per line

...

$ wc --help | grep -- '  -l'
    -l, --lines            print the newline counts

PS:注ls-<number-one> | wc-<文字-l>


10
のほとんどのバージョンは、出力がパイプである場合に自動的にls実行し-1ます。
デニスウィリアムソン

3
@Dennisそれは興味深いです。アプリケーションがその出力がパイプに送られることを伝えることができることを知りませんでした。
xenoterracide

1
このバージョンはより明確なので、このバージョンを使用しました。ただし、はい、lsがパイプされている場合は-1を使用します(試してみてください:ls | cat)。-1構文はより明確です。
ガベ。

3
@xenoterracide:バッシュ:[[ -p /dev/stdin ]] && echo "stdin is from a pipe"
デニスウィリアムソン

2
私のテストでは、ファイル名のソートを回避するために-fオプションも提供する方が大幅に高速でした。残念ながら、ファイル名に改行が含まれていると、間違った答えが返されます。
サミュエルエドウィン区

10

おそらくls/ wcペアを使用した最も完全な答えは

ls -Aq | wc -l

ドットファイルをカウントする場合、および

ls -q | wc -l

そうでなければ。

  • -Aドットファイルをカウントすることですが、とを省略...ます。
  • -qls非グラフィック文字、具体的には改行文字をで置換し?、ファイルごとに1行出力します

lsターミナルから1行の出力を取得するには(つまり、にパイプせずにwc)、-1オプションを追加する必要があります。

lscoreutils 8.23 でテストされた動作)


2
あなたが言ったように、-1必要はありません。「コンソール出力を使用してファイル名の改行を適切に処理する」に関しては、これは「印刷できないファイル名文字と<tab>文字の各インスタンスを強制的に書き込む」-qスイッチ(-bポータブルであるためではなく使用する必要があるため)<question-mark>( '?')文字として。実装は、出力が端末デバイスに対するものである場合、デフォルトでこのオプションを提供する場合があります。たとえばls -Aq | wc -l、すべてのファイル/ ls -qp | grep -c /
ディレクトリ

ご意見ありがとうございます。に変更さ-bれました-q
フレックス

7

現在のディレクトリに少なくとも1つの非隠しファイルが含まれていることがわかっている場合:

set -- *; echo "$#"

これは、すべてのグロブに明らかに一般化できます。

スクリプトでは、これには位置パラメータを上書きするという不幸な副作用があります。サブシェルを使用するか、次のような関数(Bourne / POSIXバージョン)を使用することで、この問題を回避できます。

count_words () {
  eval 'shift; '"$1"'=$#'
}
count_words number_of_files *
echo "There are $number_of_files non-dot files in the current directory"

代替ソリューションは$(ls -d -- * | wc -l)です。globがの*場合、コマンドはに短縮できます$(ls | wc -l)。の出力を解析するとls常に不安になりますが、ここでは、ファイル名に改行が含まれていないか、改行が含まれていない限り機能しますls。また$(ls -d -- * 2>/dev/null | wc -l)、一致しないグロブのケースを適切に処理するという利点があります(つまり、その場合は0を返しますが、set *メソッドはグロブが空かどうかを手間をかけずにテストする必要があります)。

ファイル名に改行文字が含まれる可能性がある場合は、代わりにを使用します$(ls -d ./* | grep -c /)

一致するファイルが多数ある場合、globの展開を渡すことに依存するこれらのソリューションlsは、引数リストが長すぎるエラーで失敗する可能性があります。


1
本当に13,923の位置パラメータを作成しますか?そして、ローカル変数を作成するlocalか、それを削除する必要があります:eval $1=$#またはuse echo $#and do だけですnumber_of_files=$(count_words *)
デニスウィリアムソン

1
@Dennis:ポイントの一部はフォークを避けることでした。これは21世紀の関心事ではないと思います。OK、非POSIXシェルはもう気にしないので、一時変数を回避できたと思います。
ジル

なぜ1を差し引いたのですか$#(編集前にそれをしていませんでした)?
デニスウィリアムソン

@Dennis:私はまだ分岐を避け(ルーターなどのCPUの遅いマシンでは違いがあります)、変数名をとして渡します$1。したがって、カウントしたいのは、最初のパラメーターではないパラメーターの数です。(shift変数名を保持する必要があるため、使用できません。)(今、最初の行について尋ねたら...)
ジル

@Dennis:考えてみると、タイミングが合ってshiftいれば使えます。
ジル

7

私はdu --inodes便利だと感じましたが、どのバージョンがdu必要なのかわかりません。findおよびを使用する代替アプローチよりも大幅に高速である必要がありwcます。

Ubuntu 17.10では、以下が機能します。

du --inodes      # all files and subdirectories
du --inodes -s   # summary
du --inodes -d 2 # depth 2 at most

と組み合わせて| sort -nr、含まれるiノードの数で降順​​でソートします。


5

-Uを追加する場合、ls / wcペアを使用している間は、はるかに高速になります(ソートしないでください)。

ls -AqU | wc -l

1
-Uただし、GNU固有です。
ステファンシャゼル16年

4

treeコマンドをインストールしたら、次を入力します。

tree

隠しファイルも必要な場合:

tree -a

Debian / Mint / Ubuntu Linuxを使用している場合は、次のコマンドを入力してtreeコマンドをインストールします。

sudo apt-get install tree

オプション-Lは、ディレクトリツリーの最大表示レベルを指定するために使用されます。treeコマンドは、ファイルの数だけでなく、ディレクトリの数もカウントします。ディレクトリツリーの必要なレベルを考慮します。


ツリーを入力すると、現在のディレクトリの画面に一種のツリー出力が表示されますが、ファイル数が表示されている場所がわかりません。
チャールズダーウィン

2
find -maxdepth 1 -type f -printf . | wc -c
  • -maxdepth 1find再帰的になり、デフォルトで再帰的です
  • -type f ファイルのみが含まれます
  • -printf .かわいい感じです。ファイル名の代わりにファイルごとにドットを出力します。これにより、任意のファイル名を処理できるようになり、データも保存されます。ドットを数えるだけです:)
  • | wc -c 文字を数えます

1

パイプなし、弦のコピーなし、フォークなし、ライナーなし

$ fcount() { local f i=0; for f in *; do let i++; done; echo $i; }; fcount

1
ディレクトリにファイルがない場合、値1を与えます。ファイルをカウントせず、ファイルとディレクトリをカウントします。
スティーブ

1

Gillesが投稿しものに沿った別のテクニックを次に示します。

word_count () { local c=("$@"); echo "${#c[@]}"; }
file_count=$(word_count *)

これにより、13,923個の要素を持つ配列が作成されます(ファイルがいくつある場合)。


そのc配列のポイントは何ですか?word_count() { echo "$#"; }十分でしょう @Gillesソリューションのポイントは、返された変数にカウントを格納して、コマンド置換(ksh93以外のシェルでのフォークとパイプが必要)を使用する必要がないようにすることです。
ステファンシャゼラス16年

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

これは、現在のディレクトリ内のファイルのみを一覧表示できます。


find . -type f現在のディレクトリ内、および再帰的にサブディレクトリ内でファイルを検索します。
ダグ

0

これを試してみてください

echo $((`ls -l | wc -l` -1 ))


0

以前に与えられたいくつかの答えを改善しますが、今回は明示的に行います。

$ tree -L 1 | tail -n 1 | cut -d " " -f 3

tailやなどの大好きなコマンドの使用に注目する価値がありcutます。また、ツリーはデフォルトでは使用できないことに注意してください。上記のコマンドは、最初にレベル1のディレクトリに関する情報をキャプチャし、次にtail -n 1目的の最終行を取得し、最終的cutに3番目の単語を取得します。

たとえば、次の場所にあり/ます。

/ $ tree -L 1
.
├── 1
├── bin -> usr/bin
├── boot
├── dev
├── etc
├── home
├── lib -> usr/lib
├── lib64 -> usr/lib64
├── lost+found
├── media
├── mnt
├── opt
├── proc
├── root
├── run
├── sbin -> usr/sbin
├── srv
├── sys
├── tmp
├── usr
└── var

20 directories, 1 file
/ $ tree -L 1 | tail -n 1
20 directories, 1 file
/ $ tree -L 1 | tail -n 1 | cut -d " " -f 3
1

次に、ディレクトリの数を尋ねるのはどうですか?



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