Підраховуйте загальну кількість файлів у конкретному каталозі із конкретним розширенням


32

Я хочу порахувати загальну кількість файлів у конкретному каталозі, який закінчується розширенням ".mp4".

Я отримую наступну команду:

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

Він підраховує всі файли в конкретному каталозі, але я хочу кількість файлів, які закінчуються розширенням .mp4.

Чи є для цього якась команда Ubuntu?


2
Проста, правильна, пряма відповідь - це @ louis-matthijssen. ls -1обробка символів нового рядка робить у цьому випадку розумним аналіз lsрезультатів. Позначений неправильно для використання прапора -R.
Рмано

Відповіді:


19

Тут ви можете зробити так

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

Це дає вам рахунок


5
Чому -R? Навіщо робити повні, statколи вам просто потрібно ім'я файлу? Чому ні ls -1 *.jpg| wc -l? (нормально, не працює, якщо у вас є назви файлів із новими рядками. У такому випадку ви цього заслуговуєте ;-) ...)
Rmano

2
... і питання було "підрахунок кількості файлів у каталозі". Крім того, у цьому рекурсивно буде перераховано весь вміст підкаталогів, ім'я яких закінчується .jpg , а не файли в підкаталогах, що закінчуються на .jpg. Ви коли-небудь тестували його?
Рмано

1
У запитанні йдеться про "файли у певному каталозі", що означає, що підкаталога рекурсія не потрібна.
Девід Річербі,

1
Це також не вдається, якщо в каталозі занадто багато файлів (тому що *.jpgвін розширений оболонкою, а не ls) і якщо є файли, імена яких починаються з дефісів.
Девід Річербі,

2
@DavidRicherby Це пропускає імена, які починаються з .. Але насправді це добре працює з дефісами в іменах, за винятком випадків, коли /path/to/dirпорожній рядок або відносний шлях починається з дефісу. Але я помилявся раніше , сказав, що lsзамінює символів на ?. Це трапляється, коли stdout є терміналом, але тут вихід є трубою, тому lsнадсилає всі символи з назви файлів на wc. Це робить цю відповідь помилковою без позначення -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) /usr/bin/printf . З -exec printf x \;, це потрібно зробити один раз для кожного файлу .
Елія Каган

-printfне підтримується в POSIXfind , тому я його не використовував.
l0b0

1
Ні те, -mindepthі -maxdepthщо ви використовували.
Елія Каган

Добре, я не брав цього питання!
l0b0

BSD findмістить -mindepthі , -maxdepthале не містить , -printfтак що я ціную включення обох.
Йосип

11

Цей файл знаходить, сортує та перераховує всі файли за розширенням у порядку:

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

Відмінно! Я просто додав би | sort -rnв кінці, а може, і -mindepth 1просто поточний реж.
Пабло А

І, можливо, труба, щоб head -nдістатися до вершини n.
Раман

така чудова відповідь, велике спасибі
Денніс Голомазов

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прапора.


Не впевнений, чому це було знято, це працює
Пантера

Оскільки *.mp4він розширений оболонкою, lsце не вдасться, якщо .mp4в каталозі так багато файлів, що список їх не може бути переданий lsяк аргументи.
Девід Річербі,

@Rmana Перевірте його в каталозі, що містить файл під назвою--.mp4
Девід Річербі,

@DavidRicherby так, ви праві. --вирішить другу справу; колишній підніме повідомлення про помилку (потрібно багато файлів!) та ще одне приємне запитання. Кутові корпуси, але варто помітити, так.
Рмано

1
@Rmano Без додавання -qабо -b, це не переносить нові рядки у назви файлів. Якщо ви біжите ls -1 *.mp4зі свого терміналу без труби, він lsбачить, що його виведення є терміналом і приймається -qяк мається на увазі, друкуючи ?s Але така поведінка зникає, коли вихідний сигнал є трубопровідним. ls -1 *.mp4 | wc -lперевитрати, якщо є нові рядки. ls -1 *.mp4 | catпоказує, що wc«бачить». (Аналогічно -1мається на увазі, коли stdout не є терміналом, тому це необов'язково.) 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

не дає рахунку
Пантера

передав його мені при використанні зwc -l
Back.Slash

використовуйте ls без трубопроводів, щоб отримати греп і скоротити свою відповідь. Він був розміщений принаймні двічі зараз.
Пантера

@ bodhi.zazen ls /directory/*.mp4змушує оболонку розширити глобус і виконати щось на кшталт ls /directory/file1.mp4 /directory/file2.mp4 ...Це не вдасться, якщо каталог містить більше mp4-файлів, ніж можна передавати як аргументи ls.
Девід Річербі,

@DavidRicherby - це не моя команда ls, я використовую find;)
Panther


0
ls | grep --count \.csv$

Замініть (.csv потрібним розширенням)

Пояснення: Я думаю, що проста схема полягає в тому, щоб отримати список файлів і порахувати розширення грепом. \.щоб відповідати .і $відповідно до розширення на кінці лінії. Це працює, тому що, коли вихід ls є конвеєрним, по одному рядку надсилається одне ім’я файлу, що ви можете перевірити, запустивши:

ls | cat

1
Зауважте, що замість цього grep --countви можете також використовувати grep -c.
Mohsin Raza

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.