特定のディレクトリにある特定の拡張子を持つファイルの総数を数える


32

「.mp4」拡張子で終わる特定のディレクトリ内のファイルの総数をカウントします。

私は次のコマンドを取得しています:

ls -F |grep -v / | wc -l

特定のディレクトリ内のすべてのファイルをカウントしますが、拡張子が.mp4のファイルのカウントが必要です。

そのためのUbuntuコマンドはありますか?


2
シンプルで正確な、簡単な答えは@ louis-matthijssenです。ls -1この場合、改行文字の処理により、ls出力を解析するのが賢明になります。マークされたものは、-Rフラグの使用に誤りがあります。
Rmano 14

回答:


19

ここでは、この方法で行うことができます

ls -lR /path/to/dir/*.jpg | wc -l

これはあなたにカウントを与えます


5
なぜ-Rstatファイル名だけが必要なときにフルを実行するのはなぜですか?どうしてls -1 *.jpg| wc -l?(OK、改行を含むファイル名がある場合は機能しません。その場合、あなたはそれに値します;-) ...)
Rmano

2
...そして質問は「ディレクトリ内のファイルの数を数える」ことでした。さらに、これは、名前が.jpg終わるサブディレクトリのすべてのコンテンツを再帰的にリストします。テストしたことがありますか?.jpg
Rmano 14

1
質問は「特定のディレクトリ内のファイル」と言っていますが、これはサブディレクトリの再帰が望ましくないことを意味します。
デビッドリチャービー14

1
また、ディレクトリ内のファイルが多すぎる場合(*.jpgによってではなくシェルによって展開されるためls)、および名前がハイフンで始まるファイルがある場合にも失敗します。
デビッドリチャービー14

2
@DavidRicherbyこれは、で始まる名前をスキップし.ます。ただし/path/to/dir、空の文字列またはハイフンで始まる相対パスの場合を除き、実際には名前にハイフンが含まれていても問題ありません。しかし、文字をに置き換えると言ったのは間違っていlsました?。stdoutが端末の場合に発生しますが、ここでは出力がパイプなのでls、ファイル名からのすべての文字をに送信しますwc。ファイル名には改行を含めることができるため、その動作を変更するためのor フラグがないと、この答えが間違って-q-bいます。l0b0の答えにはこれらの問題はありません
エリアケイガン

42

残念ながら、この良性の問題は、すべてのファイル名をサポートし、移植可能な方法で解決するのは困難です。これは安全です(隠しファイル、スペースを含むパス、ダッシュ、さらには改行も処理します)およびPOSIX互換です:

find /path/to/directory -mindepth 1 -type f -name "*.mp4" -printf x | wc -c

再帰的にしたくない場合は、単に追加し-maxdepth 1ます。

ls出力を解析しないでください。

テスト:

$ cd -- "$(mktemp -d)"
$ touch -- -foo.mp4 .bar.mp4 .bat.mp4 'baz.mp4
> ban.mp4'
$ find . -mindepth 1 -type f -name "*.mp4" -exec printf x \; | wc -c
4

受け入れられた答えと比較しください:

$ ls -lR ./*.mp4 | wc -l
3

または他の提案:

$ find . -name "*.mp4" | wc -l
5
$ ls -1 *.mp4 | wc -l
ls: invalid option -- '.'
Try 'ls --help' for more information.
0
$ find . -name "*.mp4" | wc -c # Answer fixed at a later time
51
$ find . -name "*.mp4" | wc -l
5
$ find . | grep -i ".mp4$" | wc -l
5
$ ls . | grep ".mp4$" | wc -l
3

2
この答えは正確で堅牢ですが、の-printf x代わりに使用できます-exec printf x \;。それは次のようになりますfind /path/to/directory -mindepth 1 -type f -name "*.mp4" -printf x | wc -c する必要はありません-exec外部のprintf多くのファイルがあることでしょうがある場合、コマンド、非常に遅いが、ためfindに持っているフォーク(2)その後、自身のコピーをオフと(2)はexecve /usr/bin/printf。で-exec printf x \;、それは各ファイルに対して一度行わなければなりません。
エリアカガン

-printfPOSIXではサポートされてfindいないため、使用しませんでした。
l0b0

1
使用していない、も-mindepthありません-maxdepth
エリアケイガン

良い点、私はそれを拾っていませんでした!
l0b0

BSDにfindは含まれていますが含まれ-mindepth-maxdepthいません-printfので、両方が含まれていることに感謝しています。
ジョセフ

11

これは、すべてのファイルを拡張子ごとに順番に検索、ソート、およびリストします。

find . -type f | sed 's/.*\.//' | sort | uniq -c

優れた!| sort -rn最後にa を追加し、おそらく-mindepth 1現在のディレクトリだけを追加します。
パブロA

パイプしhead -nて上位nを取得します。
ラマン

このような素晴らしい答え、どうもありがとう
Dennis Golomazov

5

次のコマンドのように非常に簡単だと思います。

$ find . -name "*.mp4" | wc -l
8

または

$ find . | grep -i ".mp4$" | wc -l
8

上記のコマンドはファイル名とディレクトリ名の数を計算すると思います *.mp4

したがって、次のように-type fオプションをfindパラメーターとして使用することをお勧めします。

$ find . -name "*.mp4" -type f | wc -l
8

また、次のls -lRように使用できますfind .


2

使用できますls -1 *.mp4 | wc -l

これは.mp4、で終わるすべてのファイルをリストし、各ファイルを新しい行(ls -1 *.mp4)に出力し、出力をパイプしwcて、-lフラグを使用して新しい行の数をカウントします。


なぜこれがダウン投票されたのかわからない、それが機能する
パンサー14

以来*.mp4、シェルによって展開されている、ではないls非常に多く存在する場合、これは失敗します.mp4それらのリストをに渡すことができないというディレクトリ内のファイルls引数として。
デビッドリチャービー14

@Rmanaという名前のファイルを含むディレクトリでテストします--.mp4
デビッドリチャービー14

@DavidRicherbyはい、あなたは正しいです。--2番目のケースを解決します。前者は、エラーメッセージ(多くのファイルが必要です!)と、ここに別の良い質問が表示されます。コーナーケースですが、気付く価値があります。
Rmano 14

1
@Rmano -qまたはを追加-bないと、ファイル名の改行を許容しませls -1 *.mp4パイプなしで端末から実行するlsと、そのstdoutが端末であることが-qわかり、暗黙的に?sを出力します。しかし、出力がパイプされると、その動作はなくなります。ls -1 *.mp4 | wc -l改行がある場合は超過します。「見る」ls -1 *.mp4 | catものを示しますwc。(同様に、-1stdout 端末ではない場合に暗示されるため、オプションです。)ls -1q -- *.mp4 | wc -lほとんど機能しますが、.mp4ファイルがゼロではありません。
エリアケイガン

0

これにより、.mp4のファイルのリストが表示されます。

ls /path/to/directory | grep ".mp4$"

と組み合わせると、wc -lカウントが得られます

ls /path/to/directory | grep ".mp4$" | wc -l

検索にサブディレクトリを含める場合

ls -lR /path/to/directory | grep ".mp4$" | wc -l

カウントしない
パンサー14

と一緒に使用されたときに私にそれを与えたwc -l
Back.Slash 14

パイプなしでlsを使用してgrepを実行し、答えを短くします。現在、少なくとも2回投稿されています。
パンサー14

@ bodhi.zazenを使用するls /directory/*.mp4と、シェルはglobを展開しls /directory/file1.mp4 /directory/file2.mp4 ...、ディレクトリに引数として渡すことができるmp4ファイルよりも多くのmp4ファイルが含まれている場合、これに失敗しlsます。
デビッドリチャービー14

@DavidRicherby-それは私のlsコマンドではなく、findを使用します;)
パンサー


0
ls | grep --count \.csv$

置換(.csvを目的の拡張子に置き換えます)

説明:単純なスキームは、ファイルのリストを取得し、grepで拡張子をカウントすることだと思います。\.一致する.$行の末尾に拡張子を一致させます。lsの出力がパイプされると、1行に1つのファイル名が送信されるため、動作します:

ls | cat

1
の代わりにをgrep --count使用することもできますgrep -c
モーシンラザ

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