Как использовать туалет и передающий по каналу для нахождения, сколько файлов и каталогов находится в определенном каталоге?

en_IE.UTF-8 Английский язык (Ирландия), локаль имеет все вещи, которые Вы просите:

  • Измерительная метрика — да
  • 24-часовой формат времени — да
  • Рабочая неделя запускается в понедельник — да
  • Числовая дата в (что-то, по крайней мере, напоминающее) формат ISO, yyyy-mm-dd — нет, это эта локаль это dd/mm/yy. Но это кажется достаточно близким к тому, к чему Вы привыкли
  • Неофициальная дата является dd/mm, не наоборот — да
  • Размер листа А4 — да
  • Европейская валюта — да
  • Система обменивается сообщениями на английском языке — да

Я на самом деле использую эту локаль, даже при том, что я нахожусь в Амстердаме, поскольку нет никакого английского языка (Paneuropean) локаль, о которой я знаю.

BTW. не делают ошибку выбора ga_IE.UTF-8 Ирландский язык (Ирландия) локаль, поскольку это - ирландский гэльский язык.

10
02.08.2016, 11:46
4 ответа

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

$ ls -1
dir1
dir2
dir3
fileA
fileB
fileC

Пример

Создайте вышеупомянутые демонстрационные данные в пустом каталоге.

$ mkdir dir{1..3}
$ touch file{A..C}

Проверьте его:

$ ls
dir1  dir2  dir3  fileA  fileB  fileC

Теперь для подсчета Вас может использовать wc -l считать количество строк, которые соответствуют файлу или каталогу в ls -1 вывод.

$ ls -1 | wc -l
6

(обратите внимание однако, что это не включает скрытые файлы),

Подсчет файлов или каталогов, просто не вместе

Для подсчета любого файлами или каталогами, необходимо изменить тактику немного. В этом случае я использовал бы ls -l так как это показывает то, что является каталогом и что является файлом.

Пример

$ ls -l
total 12
drwxrwxr-x 2 saml saml 4096 Nov 16 09:48 dir1
drwxrwxr-x 2 saml saml 4096 Nov 16 09:48 dir2
drwxrwxr-x 2 saml saml 4096 Nov 16 09:48 dir3
-rw-rw-r-- 1 saml saml    0 Nov 16 09:49 fileA
-rw-rw-r-- 1 saml saml    0 Nov 16 09:49 fileB
-rw-rw-r-- 1 saml saml    0 Nov 16 09:49 fileC

Затем мы можем использовать grep отфильтровывать каталоги или не-каталоги как так:

# directories
$ ls -l | grep "^d"
drwxrwxr-x 2 saml saml 4096 Nov 16 09:48 dir1
drwxrwxr-x 2 saml saml 4096 Nov 16 09:48 dir2
drwxrwxr-x 2 saml saml 4096 Nov 16 09:48 dir3

# regular files
$ ls -l | grep "^-"
-rw-rw-r-- 1 saml saml    0 Nov 16 09:49 fileA
-rw-rw-r-- 1 saml saml    0 Nov 16 09:49 fileB
-rw-rw-r-- 1 saml saml    0 Nov 16 09:49 fileC

Теперь просто используйте wc -l снова считать вышеупомянутое:

# directories
$ ls -l | grep "^d" | wc -l
3

# regular files
$ ls -l | grep "^-" | wc -l
3

Хотя, можно избежать wc в целом, и использование grep -c опция:

$ ls -l | grep -c '^d'

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

Рекурсия

Если необходимо найти файлы и каталоги рекурсивно под /usr/bin затем Вы, вероятно, захотите изменить тактику полностью и использовать другой названный инструмент find.

Пример

$ find /usr/bin | wc -l
4632

(хотя выше /usr/bin самостоятельно включен в количество),

Те же методы, которые я использовал выше, могли использоваться использование ls сделать что-то подобное, но ls обычно не хороший инструмент для парсинга вывода. find с другой стороны, был создан для этого, и предложения переключаются для нахождения любого файлами или каталогами.

# find files
$ find /usr/bin -type f

# find directories
$ find /usr/bin -type d

(отметьте это на этот раз, find включает скрытые файлы (кроме . и ..)).

новые строки?

Я никогда не выяснял, почему символ новой строки является допустимым символом для использования при создании имен файлов или имен каталогов. Таким образом, методы обсуждены выше использования wc и ls не спорил бы с ними, поэтому используйте их с этим в памяти.

Пример

Создайте каталог и имя файла с новыми строками.

$ mkdir $'dir4\n5'
$ touch $'fileD\nE'

ls показывает им правильно:

$ ls -1
dir1
dir2
dir3
dir4?5
fileA
fileB
fileC
fileD?E

Но wc считает каталоги и файлы, которые содержат новые строки как 2 объекта, не один.

$ ls -1 | wc -l
10

Один метод для обхождения этого, при использовании реализации GNU find должен использовать findспособность распечатать что-то еще вместо каждого файла, что это находит и затем считает их вместо этого.

Пример

$ find . -printf . | wc -c
9

Здесь мы находим все в текущем каталоге (кроме ..) и печать точки (.) для каждого и затем подсчета использования точек wcспособность считать байты вместо строк, wc -c.

Ссылки

13
27.01.2020, 20:00
  • 1
    В то время как файлы в /usr/bin все собираются быть хорошо отформатированными (и также не будет содержать пробелы, так технически Вы могли даже просто echo * | wc -w), стоит отметить, что все они повредятся на именах файлов, содержащих новые строки. –  evilsoup 16.11.2013, 17:07
  • 2
    @evilsoup - нет я не верю ls -l или ls -1 повредит b/c, мы считаем строки, не слова! find может повредиться, но снова, мы считаем строки не словами. –  slm♦ 16.11.2013, 17:21
  • 3
    То, что я имею в виду, - то, что это будет (я думать, я нахожусь в Windows прямо сейчас, таким образом, я не могу протестировать), повреждение, если файлы содержат новые строки. Так touch $'foo\nbar' в рамках пустого каталога, сопровождаемого одной из Ваших команд (говорят ls -1 | wc -l) сообщат два файла, а не один - потому что тот один файл является двумя строками до wc затронут. Если ls новые строки замен с некоторым другим символом (я не думаю, что он делает, но снова я не имею возможности тестировать прямо сейчас). спасибо –  evilsoup 16.11.2013, 17:33
  • 4
    @evilsoup - корректный символ новой строки. легальный символ. для имен файлов и методов не смог бы спорить с теми типами имен файлов правильно. –  slm♦ 16.11.2013, 19:54
  • 5
    @StephaneChazelas - wc -c проблема при подсчете периодов? –  slm♦ 17.11.2013, 18:19

Вы не сказали, хотите ли Вы весь файл под/usr/bin рекурсивно или только под первым уровнем. Кроме того, как Вы собираетесь получить слова, которые Вы считаете? Обычный способ узнать состоит в том, чтобы работать, находят в туалет. Как это: найдите/usr/bin |, туалет-l Находка перечислит все там, каталоги и файлы. Туалет-l будет считать все строки в выводе находки. Действительно ли это - присвоение класса? Хорошо, если это всего лишь, я задавался вопросом, почему Вам была нужна эта информация так, чтобы я мог адаптировать ответ более тщательно. Сообщите мне, нужен ли Вам больше. Коста

0
27.01.2020, 20:00

В ударе, без внешних инструментов.

cd dir/ || exit; shopt -s nullglob; shopt -s dotglob; count=(*); echo "${#count}"

В ударе, без внешних инструментов и рекурсии.

shopt -s globstar; shopt -s dotglob 
for dir in **/*/; do 
  unset d f
  for files in "$dir"*; do 
    [[ -f $files ]] && ((++f))
    [[ -d $files ]] && ((++d))
  done; 
  printf '%s\n' "$dir -  files: ${f:-0} - directories: ${d:-0}"
done
0
27.01.2020, 20:00
  • 1
    Обратите внимание, что второе следовало бы за символьными ссылками при рекурсивном вызове (и считало бы символьные ссылки на регулярные файлы, поскольку регулярные файлы и символьные ссылки на директоров как директора), не будет считать файлы и каталоги в текущем каталоге и не рассчитал бы . ни .. записи. Можно хотеть снять неоднозначность файла по сравнению с регулярным файлом. –  Stéphane Chazelas 16.11.2013, 22:49

Если Вы хотите свалить повреждение количества каждого типа файла рекурсивно под некоторым dir с GNU find, Вы могли сделать:

find /some/dir/. ! -name . -printf '%y\n' | sort | uniq -c | sed '
  s/f/regular files/;t
  s/d/directories/;t
  s/l/symbolic links/;t
  s/s/Unix domain sockets/;t
  s/b/block devices/;t
  s/c/character devices/;t
  s/p/FIFOs/;t
  s/D/Doors/;t
  s/n/network special files/;t
  s/.$/others (&)/'

На /usr/bin в моей системе, которая дает:

   3727 regular files
    710 symbolic links

На /dev:

     83 block devices
    203 character devices
     31 directories
    426 symbolic links
      1 FIFOs
      1 Unix domain sockets

Для символьных ссылок, если Вы считали бы их как тип файла, они указывают на, а не symbolic links, можно изменить его на:

find /some/dir/. ! -name . -printf '%Y\n' | sort | uniq -c | sed '
  s/f/regular files/;t
  s/d/directories/;t
  s/N/broken symbolic links/;t
  s/s/Unix domain sockets/;t
  s/b/block devices/;t
  s/c/character devices/;t
  s/p/FIFOs/;t
  s/D/Doors/;t
  s/n/network special files/;t
  s/.$/others (&)/'

Который теперь дает для моего /usr/bin:

      1 directories
   4434 regular files
      2 broken symbolic links

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

Ни один из тех не рассчитывает . и ... Если Вы хотели их включенный (почему был бы Вы?), нет никакого другого пути с find чем предполагают, что они там для каждого каталога и систематически считают их:

find /some/dir/. -printf '%y\n' \( -name . -printf 'd\n' -o \
  -type d -printf 'd\nd\n' \)  | sort | uniq -c | sed '
  s/f/regular files/;t
  s/d/directories/;t
  s/l/symbolic links/;t
  s/s/Unix domain sockets/;t
  s/b/block devices/;t
  s/c/character devices/;t
  s/p/FIFOs/;t
  s/D/Doors/;t
  s/n/network special files/;t
  s/.$/others (&)/'

Который затем дает на моем /usr/bin:

      2 directories
   3727 regular files
    710 symbolic links

Если у Вас нет доступа к GNU find, можно переписать первый как:

find /some/dir/. ! -name . \( \
  -type f -exec printf '%.0sregular files\n' {} + -o \
  -type d -exec printf '%.0sdirectories\n' {} + -o \
  -type l -exec printf '%.0ssymbolic links\n' {} + -o \
  -type s -exec printf '%.0sUnix domain sockets\n' {} + -o \
  -type b -exec printf '%.0sblock devices\n' {} + -o \
  -type c -exec printf '%.0scharacter devices\n' {} + -o \
  -type p -exec printf '%.0sFIFOs\n' {} + -o \
  -exec printf '%.0sothers\n' {} + \) | sort | uniq -c

Теперь, строго говоря, мы не считали файлы, но записи каталога. Каталог как /usr/bin обычно имеет несколько записей, которые указывают на тот же файл. Например, здесь, я имею:

$ ls -lid /usr/bin/{nvi,nview,nex}
672252 -rwxr-xr-x 3 root root 434616 May 25 07:40 /usr/bin/nex
672252 -rwxr-xr-x 3 root root 434616 May 25 07:40 /usr/bin/nvi
672252 -rwxr-xr-x 3 root root 434616 May 25 07:40 /usr/bin/nview

Это - 3 записи каталога (иначе имена файлов иначе жесткие ссылки) в тот же файл (тот с inode 672252. Считать файлы вместо записей каталога и с GNU find и GNU uniq (игнорирование . и .. файлы, которые так или иначе являются жесткими ссылками на другие каталоги):

find /some/dir/. ! -name . -printf '%y\t%D:%i\n' |
  sort -u |
  cut -f1 |
  uniq -c |
  sed '
    s/f/regular files/;t
    s/d/directories/;t
    s/l/symbolic links/;t
    s/s/Unix domain sockets/;t
    s/b/block devices/;t
    s/c/character devices/;t
    s/p/FIFOs/;t
    s/d/Doors/;t
    s/n/network special files/;t
    s/.$/others (&)/'

На моем /usr/bin, это дает:

   3711 regular files
    710 symbolic links
5
27.01.2020, 20:00

Теги

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