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

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

Я нашел этот код здесьhttps://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x700.htmlчто наглядно показывает мне количество файлов в моем каталоге.

ls -1 | wc -l

но я хочу знать только, сколько из этих файлов имеют имена, начинающиеся с 2009 (например 20091210_005037.nc).

Я попробовал ls -1 | wc -l 2009*, но это медленно выводит список всех файлов и, похоже, не дает мне номера.

решение1

set -- 2009*
echo "$#"

Это устанавливает список позиционных параметров ( $1, $2, ..., и т.д.) для имен, соответствующих 2009*. Длина этого списка составляет $#.


Проблема в ls -1 | wc -l 2009*том, что вы выполняете wc -lнапрямую в файлах, соответствующих 2009*, подсчитывая количество строк в каждом. Между тем, ls -1пытается записать в стандартный ввод wc, который wcне читается, поскольку ему был дан явный список файлов для работы.

Вы могли бы использовать ls -d 2009* | wc -l. Это перечислило бы все соответствующие имена 2009*(используя lswith -d, чтобы не перечислять содержимое каталогов), и подсчитало бы количество строк в выводе. Обратите внимание, что это -1не нужно, если вы передаете результат lsкуда-то (если только lsэто не псевдоним или функция оболочки, которая принудительно выводит столбец).

Обратите внимание, что это даст вамнеправильныйподсчитать, содержит ли имя файла символ новой строки:

$ touch '2009
> was
> a
> good
> year'
$ ls
2009?was?a?good?year
$ ls -l
total 0
-rw-r--r--  1 kk  wheel  0 May 28 11:09 2009?was?a?good?year
$ ls -1
2009?was?a?good?year
$ ls | wc -l
       5
$ ls -1 | wc -l
       5

Однако:

$ set -- 2009*
$ echo "$#"
1

(использование setи вывод $#дополнительно не использует никаких внешних команд в большинстве оболочек)


Использование findдля рекурсивного подсчета:

find . -type f -name '2009*' -exec echo . \; | wc -l

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

С нами findмы сможем более тщательно контролироватьтипфайла, который мы считаем. Выше мы явно проверяем наобычные файлыwith -type f(т. е. не каталоги и другие типы файлов). Шаблон *в оболочке не различает каталоги и файлы, но zshоболочка может использовать *(.)для изменения поведения шаблона, чтобы он соответствовал только обычным файлам ( zshпользователь, вероятно, использовал бы 2009*(.)вместо 2009*в не- findвариациях выше и ниже).

Использование **in (с shopt -s globstarin bash, или set -o extended-globin yash, или в любой другой оболочке, которая может это поддерживать) для рекурсивного подсчета:

set -- **/2009*
echo "$#"

Шаблон **соответствует почти как *, но также соответствует и /по путевым именам.

решение2

Попробовал с помощью приведенной ниже команды, и она сработала нормально, и получил результат

   find . -maxdepth 1 -type f -iname "2009*" | awk '{print NR}'| sed -n '$p'

Примечание: Если вы также хотите использовать подкаталог, пожалуйста, удалите опцию maxdepth.

решение3

Спасибо всем, кто оставил комментарии, вот ответ на мой вопрос:

ls 2009* | wc -l

или используя find

find 2009* | wc -l

решение4

Подсчет количества файлов, начинающихся с определенного имени, с помощью awk.

root@ubuntu$ find . -name "2009*" | awk 'BEGIN{total=0}; {total=total+1} END {print "total files starting with 2009 is " ,total}'
total files starting with 2009 is  4

Связанный контент