
Я нашел этот код здесь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*
(используя ls
with -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 globstar
in bash
, или set -o extended-glob
in 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