Как я считаю все файлы рекурсивно через каталоги

TL, DR:

rsync -am --include='*.pdf' --include='*/' --exclude='*' ~/LaTeX/ ~/Output/

Rsync копирует источник (источники) в место назначения. Если Вы передаете *.pdf как источники, оболочка разворачивает это до списка файлов с .pdf расширение в текущем каталоге. Никакого рекурсивного обхода не происходит, потому что Вы не передали каталога как источника.

Таким образом, необходимо работать rsync -a ~/LaTeX/ ~/Output/, но с фильтром, чтобы сказать rsync копировать .pdf файлы только. Правила фильтра Rsync могут казаться пугающими, когда Вы читаете руководство, но можно создать много примеров со всего несколькими простыми правилами.

  • Включения и исключения:

    • Исключая файлы по имени или местоположением легко: --exclude=*~, --exclude=/some/relative/location (относительно исходного аргумента, например, это исключает ~/LaTeX/some/relative/location).
    • Если Вы только хотите соответствовать нескольким файлам или местоположениям, включать их, включайте каждое продвижение каталога в них (например, с --include=*/), затем исключите остальных с --exclude='*'. Это вызвано тем, что:
    • При исключении каталога это исключает все ниже его. Исключенные файлы не рассмотрят вообще.
    • При включении каталога это автоматически не включает его содержание. В последних версиях, --include='directory/***' сделает это.
    • Для каждого файла первое правило соответствия применяется (и что-либо никогда подбираемое включено).
  • Шаблоны:

    • Если шаблон не содержит a /, это относится к имени файла без каталога.
    • Если шаблон заканчивается /, это относится к каталогам только.
    • Если шаблон запускается с /, это относится к целому пути от каталога, который был передан как аргумент rsync.
    • * любая подстрока единственного компонента каталога (т.е. никогда не соответствует /); ** соответствия любая подстрока пути.
  • Если исходный аргумент заканчивается a /, его содержание копируется (rsync -r a/ b создает b/foo для каждого a/foo). Иначе сам каталог копируется (rsync -r a b создает b/a).


Таким образом здесь мы должны включать *.pdf, включайте каталоги, содержащие их, и исключите все остальное.

rsync -a --include='*.pdf' --include='*/' --exclude='*' ~/LaTeX/ ~/Output/

Обратите внимание, что это копирует все каталоги, даже те, которые не содержат файла соответствия или подкаталога, содержащего один. Этого можно избежать с --prune-empty-dirs опция (это не универсальное решение, так как Вы затем не можете скопировать каталог даже путем соответствия ему явно, но это - редкое требование).

rsync -am --include='*.pdf' --include='*/' --exclude='*' ~/LaTeX/ ~/Output/
50
19.11.2015, 19:13
10 ответов
find -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done

Благодаря Gilles и xenoterracide для безопасности/совместимости фиксирует.

Первая часть: find -maxdepth 1 -type d возвратит список всех каталогов в текущем рабочем каталоге. Это передается по каналу к...

Вторая часть: while read -r dir; do начинает некоторое время цикл - пока канал, входя, в то время как открыто (который является, пока весь список каталогов не отправляется), команда чтения поместит следующую строку в переменный "dir". Затем это продолжается...

Третья часть: printf "%s:\t" "$dir"; распечатает строку в "$dir" (который содержит одни из имен каталогов), сопровождаемый вкладкой.

Четвертая часть: find "$dir -f file" входит в список всех файлов в имени каталога, сохраненном в "$dir". Этот список отправляется в..

Пятая часть: wc -l; считает количество строк, которые отправляются в его стандартный вход.

Заключительная часть: done просто заканчивает цикл с условием продолжения.

Таким образом, мы получаем список всех каталогов в текущем каталоге. Для каждого из тех каталогов мы генерируем список всех файлов в нем так, чтобы мы могли считать их всех использованием wc -l. Результат будет похож:

./dir1: 234
./dir2: 11
./dir3: 2199
...
62
27.01.2020, 19:33
  • 1
    Всегда используйте read -r как плоскость read обратные косые черты обработок особенно. Затем echo -en "$dir:\t" снова исказит обратные косые черты; простая фиксация должна использовать printf '%s:\t' "$dir" вместо этого.Далее, $dir должен быть "$dir" (всегда используйте двойные кавычки вокруг подстановок переменных). –  Gilles 'SO- stop being evil' 18.11.2010, 03:40
  • 2
    , измененном на @Giles предложения find -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" | wc -l; done –  xenoterracide 18.11.2010, 11:30
  • 3
    Я добавляю sort -n -r -k2 в конец этого, для большого количества каталогов, так, чтобы я знал, где большая часть использования –  xenoterracide 25.01.2011, 12:45
  • 4
    Четвертая часть: найдите, что "$dir" входит в список всех файлов в имени каталога, сохраненном в "$dir". Вы забыли добавлять -type f заставить его перечислить файлы: find -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done –  Krzysztof Boduch 20.06.2014, 15:02
  • 5
    я не заставляю это работать над macOS Горной цепью 10.12.5. illegal option -- m в find команда. Я изменил его на find . -maxdepth ... и заставил это работать. –  Jeff 24.07.2017, 16:28

Попытка:

find /path/to/start/at -type f -print | wc -l

как начальная точка, или если Вы действительно только хотите рекурсивно вызвать через подкаталоги каталога (и пропустить файлы в том высокоуровневом каталоге)

find `find /path/to/start/at -mindepth 1 -maxdepth 1 -type d -print` -type f -print | wc -l
12
27.01.2020, 19:33
  • 1
    +1 для чего-то | туалет-l... подсчет слов является таким миленьким инструментом –  Johan 16.11.2010, 14:32
  • 2
    да, но это только делает 1 каталог.... Я хотел бы получить счет для всех каталогов в каталоге, и я не хочу выполнять его отдельно каждый раз, когда..., конечно, я предполагаю, что мог использовать цикл..., но я ленив. –  xenoterracide 16.11.2010, 14:49
  • 3
    find работы рекурсивно через все подкаталоги по умолчанию. Если Вы хотите, чтобы это работало в нескольких местоположениях, можно указать всех их между find и -type. –  Didier Trosset 16.11.2010, 16:33
  • 4
    , что второй, конечно, не работает.... Я попробовал его на / домой. Я добрался 698035 . Я должен заняться 6 числами. слишком рекурсивный –  xenoterracide 16.11.2010, 23:02
  • 5
    Это работает на меня - Вы уверенный, что у Вас только есть 6 файлов под /home? Я был бы на 100% уверен, что Вы не делаете. бормотание –  Cry Havok 17.11.2010, 19:28

Следующее решение считает фактическое количество используемого inodes, начинающего с текущего каталога:

find . -print0 | xargs -0 -n 1 ls -id | cut -d' ' -f1 | sort -u | wc -l

Для получения количества файлов того же подмножества используйте:

find . | wc -l

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

4
27.01.2020, 19:33
  • 1
    Хорошая идея, принимая жесткие ссылки во внимание. Принятие GNU находит, Вам не нужно столько шагов: find -printf '%i\n' | sort -u | wc -l. Если бы Вы хотели быть портативными, то Вам было бы нужно find . -exec ls -id {} + | cut … вместо этого. –  Gilles 'SO- stop being evil' 19.11.2010, 22:24

Дайте этому попытку:

find -type d -print0 | xargs -0 -I {} sh -c 'printf "%s\t%s\n" "$(find "{}" -maxdepth 1 -type f | wc -l)" "{}"'

Это должно хорошо работать, если имена файлов не включают новые строки.

1
27.01.2020, 19:33
  • 1
    ... Я только хочу видеть верхний уровень, где он составляет все под ним. просуммированный... это заканчивает тем, что печатало каждый каталог. –  xenoterracide 16.11.2010, 23:05
  • 2
    @xenoterracide: Попытайтесь добавить -maxdepth 1 сразу после первого find. Если Вы хотите включать количество подкаталогов в Вашем количестве, удалите -type f в конце (который должен был действительно быть ! -type d так или иначе, так, чтобы все файлы некаталога были бы включены). –  Paused until further notice. 17.11.2010, 01:15

Вот компиляция некоторых полезных команд списка (перехеширована на основе предыдущего пользовательского кода):

Папки списка с количеством файла:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type f | wc -l); printf "%4d : %s\n" $n "$dir"; done

Папки списка с ненулевым количеством файла:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type f | wc -l); if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Папки списка с количеством подпапки:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type d | wc -l); let n--; printf "%4d : %s\n" $n "$dir"; done

Папки списка с ненулевым количеством подпапки:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type d | wc -l); let n--; if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Перечислите пустые папки:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" | wc -l); let n--; if [ $n -eq 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Перечислите непустые папки с довольным количество:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" | wc -l); let n--; if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done
13
27.01.2020, 19:33
  • 1
    И btw.. если Вы хотите иметь вывод какой-либо из этих команд списка, отсортированных по количеству объекта.. передайте команду по каналу в вид: "a-list-command" | вид-n –  DolphinDream 16.05.2013, 19:00

Попробовать find . -type f | wc -l, это рассчитает всех файлов в текущем каталоге, а также всех файлов в подкаталогах. Обратите внимание, что все каталоги не будут считаться как файлы, только обычные файлы делают.

16
27.01.2020, 19:33

OS X 10.6 давит на команду в принятом ответе, так как в ней не указан путь для find. Вместо этого используйте:

find . -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done
2
27.01.2020, 19:33

Я знаю, что опаздываю на вечеринку, но я верю, что этот чистый bash (или другая оболочка, которая принимает двойной звездный шар) решение может быть намного быстрее в некоторых ситуациях:

shopt -s globstar    # to enable ** glob in bash
for dir in */; do a=( "$dir"/**/* ); printf "%s\t%s\n" "$dir:" "${#a[*]}"; done

вывод:

d1/:    302
d2/:    24
d3/:    640
...
2
27.01.2020, 19:33

Если у вас установлено ncdu(, которое необходимо -, когда вы хотите выполнить некоторую очистку ), просто введите cдля «Переключить отображение количества дочерних элементов». И Cна «Сортировать по элементам».

5
27.01.2020, 19:33

du --иноды

Я не уверен, почему никто (, в том числе и я ), не знал о:

du --inodes
--inodes
      list inode usage information instead of block usage

Я почти уверен, что это решает проблему ОП. Я начал часто использовать его, чтобы узнать, где находится весь хлам на моих огромных дисках (, и выгрузить его на более старый диск ).

Дополнительная информация

Если вы НЕ хотите использовать рекурсию (, которая может быть полезна в других ситуациях ), добавьте

-S, --separate-dirs
5
27.01.2020, 19:33

Теги

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