Что лучший способ состоит в том, чтобы считать количеством файлов в каталоге?

В дополнение к ответу Gilles - пока Вы не намереваетесь сделать ioctls на файле, это - просто поток. Таким образом, если Вы работали от гостя

# mkfifo /dev/fakevideo0
# ssh host cat /dev/video0 > /dev/fakevideo0

/dev/fakevideo0 будет вести себя как буфер поэтому, если Вы будете читать из него, то Вы получите поток от камеры.

10
24.12.2011, 01:31
10 ответов

Как насчет этого приема?

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

Столь же портативный как find и wc.

14
27.01.2020, 19:59
  • 1
    Это не работает (это отображается n+1 файлы в моей системе Debian). Это также не фильтрует для регулярных файлов. –  Chris Down 23.12.2011, 15:35
  • 2
    я просто дал универсальный пример. Это действительно работает, но как это работает, зависит от того, как Вы адаптируетесь find управляйте к своим определенным потребностям. Да, этот включает все каталоги, включая . (который мог бы быть, почему Вы видите результат как n+1). –  rozcietrzewiacz 23.12.2011, 17:35
  • 3
    мне нравится этот прием, очень умный; но я удивлен, что нет никакого простого простого способа сделать это! –  rahmu 23.12.2011, 18:11
  • 4
    @ChrisDown OP не указывает фильтрацию для регулярных файлов, просит количество файлов в каталоге. Для избавлений от проблемы n+1 использовать find . -maxdepth 1 ! -name . -exec echo \; | wc -l; некоторые более старые версии find не иметь -not. –  Arcege 23.12.2011, 18:50
  • 5
    Отметьте это -maxdepth не является стандартным (расширение GNU, теперь также поддерживаемое несколькими другими реализациями). –  Stéphane Chazelas 09.05.2015, 18:10

С ударом, без внешних утилит, ни циклов:

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
27.01.2020, 19:59
  • 1
    Первая печать в качестве примера 1 для пустого каталога, когда nullglob не включен. В zsh, a=(*(DN));echo ${#a} с N (nullglob) спецификатор не приводит к ошибке для пустого каталога. –  nisetama 12.05.2016, 02:17

Yoc может использовать такую конструкцию:

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

Но я боюсь, Вы можете католическая ошибка как Argument list too long. в случае, если у Вас есть слишком много файлов в каталоге. Однако я протестировал его на каталоге с 10 миллиардами файлов, и это работало хорошо.

1
27.01.2020, 19:59
  • 1
    Это не будет работать на скрытые файлы также, если оболочка не будет настроена для расширения тех, которые имеют *. –  Lekensteyn 23.12.2011, 13:53
  • 2
    gnu find . -maxdepth 1 -type f | wc -l –  Nikhil Mulley 23.12.2011, 16:41
  • 3
    @Rush: эта команда никогда не должна повышать "список аргумента слишком долго". То единственное происходит с внешней командой (поэтому никогда с for. А-ч –  enzotib 23.12.2011, 18:16

Попытка:

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]])'
6
27.01.2020, 19:59

Вы рассмотрели жемчуг, который должен быть относительно портативным?

Что-то как:

use File::Find;

$counter = 0;

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

find(\&wanted, @directories_to_search);
print "$counter\n";
1
27.01.2020, 19:59

Попробуйте это => Используя ls с-i (для числа узла), и-F (добавляет имя каталога с '/'), опции.

ls -ilF | egrep -v '/' | wc -l
0
27.01.2020, 19:59
find . ! -name . -prune -print | grep -c /

должно быть довольно портативно к системам после 80-х годов.

Это подсчитывает все записи каталога, кроме . и .. в текущем каталоге.

Чтобы подсчитать файлы в подкаталогах, а также:

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

(что нужно быть портативным даже до Unix V6 (1975), поскольку ему не нужно -Prune )

6
27.01.2020, 19:59

С однострочником 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";'

Вы можете использовать функции perl , которые изменяют массивы, например grep или карта со второй версией. См. perldoc -f readdir для примера использования grep .

0
27.01.2020, 19:59

В дополнение к основанному наfind-ответу , предложенному Стефаном , вот ответ, совместимый с POSIX -, основанный наls:

ls -qf | tail -n +3 | wc -l
0
27.01.2020, 19:59

Самая простая версия, которую я использую постоянно и с которой у меня никогда не было проблем, это : ls -b1 | wc -l

1
27.01.2020, 19:59

Теги

Похожие вопросы