2012-02-06 5 views
380

Как я могу рекурсивно подсчитать файлы в каталоге Linux?Рекурсивно подсчитывать файлы в каталоге Linux

Я нашел это:

find DIR_NAME -type f ¦ wc -l 

Но когда я запускаю это возвращает следующее сообщение об ошибке.

находка: пути должны предшествовать выражение: |

+42

Вы сбиваете с толку разбитую полосу '' '(ASCII 166) с вертикальной полосой' '' (ASCII 124), используемой для [UNIX-конвейера] (http://en.wikipedia.org/wiki/Pipeline_ % 28Unix% 29). –

+2

@SkippyleGrandGourou Разве это не называется трубой? – DaveStephens

+18

@DaveStephens Да, это также называется. Его также называют штрихом Шеффера, verti-bar, vbar, stick, вертикальной линией, вертикальной косой чертой, баром, обелиском, glidus. – emlai

ответ

757

Это должно работать:

find DIR_NAME -type f | wc -l 

Объяснение:

  • -type f включать только файлы.
  • | (и не ¦) перенаправляет стандартный вывод find командования на стандартный ввод wc команды.
  • wc (сокращение от слова) подсчитывает символы новой строки, слова и байты на его входе (docs).
  • -l считать только символы новой строки.

Примечания:

  • Replace DIR_NAME с ., чтобы выполнить команду в текущей папке.
  • Вы также можете удалить -type f, чтобы добавить в список каталогов (и символических ссылок).
  • Возможно, эта команда будет пересобираться, если имена файлов могут содержать символы новой строки.

Объяснение того, почему ваш пример не работает:

В команде вы показали, вы не использовать «Pipe» (|) к добрейшей из соединения двух команд, но сломанный бар (¦), который оболочка не распознает как команду или что-то подобное. Вот почему вы получаете это сообщение об ошибке.

+16

'f' в' -type f' означает файлы и 'wc -l' для строк подсчета слов. –

+1

Удалите '-type f', чтобы включить каталоги в счет – phatblat

+1

Есть ли более быстрый метод? Поскольку это действительно занимает некоторое время, если вы примените его к/ – poitroae

46

Для текущего каталога:

find . -type f | wc -l 
3

Чтобы определить, сколько файлов в текущем каталоге, положить в ls -1 | wc -l. Это использует wc, чтобы выполнить подсчет количества строк (-l) на выходе ls -1. Это не считается dotfiles. Обратите внимание, что ls -l (это «L», а не «1», как в предыдущих примерах), который я использовал в предыдущих версиях этого HOWTO, фактически даст вам количество файлов, большее, чем фактическое количество. Спасибо Kam Nejad за этот момент.

Если вы хотите считать только файлы и НЕ включать символические ссылки (просто пример того, что еще вы могли бы сделать), вы могли бы использовать ls -l | grep -v ^l | wc -l (это «L», а не «1» на этот раз, мы хотим, чтобы " длинный "список здесь). grep проверяет любую строку, начинающуюся с «l» (указывая ссылку), и отбрасывает эту строку (-v).

Относительная скорость: «ls -1/usr/bin/| wc -l» занимает около 1,03 секунды на разгруженном 486SX25 (/ usr/bin/на этом компьютере имеется 355 файлов). «ls -l /usr/bin/ | grep -v ^l | wc -l» занимает около 1,19 секунды.

Источник: http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x700.html

+2

'ls -l' должен делать' stat' syscall для каждого файла, чтобы читать его размер, mtime и другие свойства, что происходит медленно. В больших каталогах (100.000+ файлов) запуск 'ls -l' может занять несколько минут. Поэтому, чтобы считать только файлы, всегда используйте 'ls -1 | wc -l'. – Marki555

+0

A 486SX25, nice – cam8001

36

Если вы хотите разбивку, сколько файлов в каждой директории под текущей директории:

for i in $(find . -maxdepth 1 -type d) ; do 
    echo -n $i": " ; 
    (find $i -type f | wc -l) ; 
done 

Это может пойти все на одной линии, конечно. В скобках уточняется, чей вывод wc -l должен смотреть (find $i -type f в этом случае).

+2

add -mindepth 1 для пропуска. – kdubs

+3

Это может застрять в каталогах с пробелами в их именах. Изменение первой строки 'find. -maxdepth 1-тип d -print0 | в то время как IFS = read -r -d '' i; do' исправляет это. См. [Как я могу прочитать файл (поток данных, переменную) по очереди (и/или поле за полем)?] (Http://mywiki.wooledge.org/BashFAQ/001) –

28

Вы можете использовать

$ tree 

после установки дерева пакет с

$ sudo apt-get install tree 

(на машине Debian/Mint/Ubuntu Linux).

Команда показывает не только количество файлов, но и количество каталогов отдельно. Опцию -L можно использовать для указания максимального уровня отображения (по умолчанию это максимальная глубина дерева каталогов).

Скрытые файлы могут быть включены также путем поставки опции -a.

+2

Это на самом деле самый простой способ увидеть количество каталогов и файлов. –

+7

На странице man: _День по умолчанию дерево не печатает скрытые файлы_. Вы должны указать параметр '-a', чтобы включить их. – eee

6

Если вы хотите знать, сколько файлов и подкаталогов существуют из настоящего рабочего каталога вы можете использовать этот Однострочник

find . -maxdepth 1 -type d -print0 | xargs -0 -I {} sh -c 'echo -e $(find {} | wc -l) {}' | sort -n 

Это будет работать в GNU аромате, и просто опустить -e от команда echo для BSD linux (например, OSX).

+2

Отличное решение! Единственная проблема, которую я нашел, это каталоги с пробелами или специальными символами. Добавьте кавычки, в которых используется имя dir: 'find. -maxdepth 1-тип d -print0 | xargs -0 -I {} sh -c 'echo -e $ (find "{}" | wc -l) "{}"' | sort -n' –

+1

Я немного изменил его, и он отлично работает для меня: 'find. -maxdepth 1-тип d -print0 | xargs -0 -I {} sh -c 'echo $ (find {} | wc -l) \\ t {}' | sort -rn | less' – Wizek

6

Если вы хотите, чтобы избежать случаев ошибки, не позволяют wc -l видеть файлы с символами новой строки (которые он будет считать, как 2+ файлы)

например Рассмотрим случай, когда у нас есть один файл с одного символа EOL в нем

> mkdir emptydir && cd emptydir 
> touch $'file with EOL(\n) character in it' 
> find -type f 
./file with EOL(?) character in it 
> find -type f | wc -l 
2 

Так, по крайней мере Gnu wc не кажется, есть возможность чтения/сосчитать оканчивающихся нулем список (за исключением из файла), самым простым решением было бы не передавать ему имена файлов, а статический вывод каждый раз, когда файл найден, напримерв том же каталоге, что и выше

> find -type f -exec printf '\n' \; | wc -l 
1 

Или, если ваш find поддерживает его

> find -type f -printf '\n' | wc -l 
1 
0

Вы можете попробовать:

find `pwd` -type f -exec ls -l {} ; | wc -l 
11

Объединение нескольких ответов здесь вместе, самое полезное решение кажется не включенных в другие категории:

find . -maxdepth 1 -type d -print0 | xargs -0 -I {} sh -c 'echo -e $(find "{}" -printf "\n" | wc -l) "{}"' | sort -n 

Он может обрабатывать нечетные вещи, такие как имена файлов, которые включают в себя круглые скобки и даже новые строки. Он также сортирует вывод по количеству файлов.

Вы можете увеличить число после -maxdepth, чтобы подсчитать подсети. Имейте в виду, что это может занять много времени, особенно если у вас есть сильно вложенная структура каталогов в сочетании с высоким числом макс.

0

Я хотел бы дать другой подход с фильтром для формата. Пример подсчитывает все доступные модули личинка ядра:

ls -l /boot/grub/*.mod | wc -l

24

На моем компьютере rsync немного быстрее, чем find | wc -l в принятом ответе. Например, вы можете рассчитывать файлы в /Users/joe/, как это:

[joe:~] $ rsync --stats --dry-run -ax /Users/joe/ /xxx 

Number of files: 173076 
Number of files transferred: 150481 
Total file size: 8414946241 bytes 
Total transferred file size: 8414932602 bytes 

Вторая строка содержит количество файлов, 150,481 в приведенном выше примере. В качестве бонуса вы также получаете общий размер (в байтах).

Примечания:

  • первая строка представляет собой подсчет файлов, каталогов, симлинками и т.д. все вместе, поэтому это больше, чем во второй строке.
  • --dry-run (или -n для краткости) опция важна, чтобы фактически не передавать файлы!
  • Параметр /xxx может быть любой пустой или не существующей папкой. Не используйте здесь /.
  • Я использовал опцию -x, чтобы «не перекрещивать границы файловой системы», что означает, что если вы выполните ее для / и у вас есть внешние жесткие диски, они будут считать только файлы в корневом разделе.
+0

Мне нравится ваша идея использования rsync здесь. Я бы никогда об этом не думал! – Qeole

+0

Спасибо @Qeole, идея не моя, хотя. Я прочитал несколько лет назад где-то, что rsync является самым быстрым для удаления папки с большим количеством файлов и вложенных папок, поэтому я подумал, что можно быстро подсчитать файлы. – psmith

+0

Пробовал это. После двух запусков для заполнения кэша fs, 'find ~ -type f | wc -l' взял 1.7/0.5/1.33 секунды (real/user/sys). 'rsync --stats --dry-run -ax ~/xxx' занял 4.4/3.1/2.1 секунды. Это около 500 000 файлов на SSD. – slim

0

ls -l | grep -e -x -e -dr | не туалет -l

список 1.Long 2.filter файлы и каталоги 3.count отфильтрованной линия не

0

Есть много правильных ответов здесь. Вот еще!

find . -type f | sort | uniq -w 10 -c 

где . папка смотреть в и 10 это количество символов, которые в группе каталога.

0

Я написал ffcnt, чтобы ускорить рекурсивный подсчет файлов при определенных обстоятельствах: вращательные диски и файловые системы, поддерживающие отображение степени.

Это может быть на порядок больше, чем ls или find основанных подходов, но YMMV.

0

С Баш:

Создайте массив записей с() и получить счетчик с #.

FILES=(./*); echo ${#FILES[@]} 

Хорошо, что не рекурсивно считать файлы, но сначала я хотел показать простой вариант. Общим вариантом использования может быть создание резервных копий файла для резервного копирования. Это создаст logfile.1, logfile.2, logfile.3 и т.д.

CNT=(./logfile*); mv logfile logfile.${#CNT[@]} 

Чтобы получить количество файлов рекурсивно мы все еще можем использовать найти таким же образом.

FILES=(`find . -type f`); echo ${#FILES[@]} 
0

find -type f | туалет -l

ИЛИ (Если каталог текущего каталога)

находкой. -тип f | wc -l

Смежные вопросы