Найти количество файлов, соответствующих шаблону в каталоге в linux
Я новичок в Linux. У меня есть каталог в Linux с примерно 250 000 файлов
Мне нужно найти количество файлов, соответствующих шаблону.
Я попытался использовать следующую команду:
ls -1 20061101-20131101_kh5x7tte9n_2010_* | wc -l
Появилось следующее сообщение об ошибке:
-bash: /bin/ls: Argument list too long
0
Пожалуйста, помогите. Спасибо заранее
Ответы
Ответ 1
Для этого может быть лучше использовать find
:
find . -name "pattern_*" -printf '.' | wc -l
В вашем конкретном случае:
find . -maxdepth 1 -name "20061101-20131101_kh5x7tte9n_2010_*" -printf '.' | wc -m
find
возвращает список файлов, соответствующих критериям. -maxdepth 1
сделает поиск только по пути, без подкаталогов (спасибо, Петеш!). -printf '.'
будет печатать точку для каждого совпадения, чтобы имена с новыми строками не wc -m
.
Тогда wc -m
укажет количество символов, которое будет соответствовать количеству файлов.
Сравнение производительности двух возможных вариантов:
Давайте создадим 10 000 файлов с этим шаблоном:
$ for i in {1..10000}; do touch 20061101-20131101_kh5x7tte9n_201_$i; done
А затем сравните время, необходимое для получения результата, с помощью ls -1...
или find...
:
$ time find . -maxdepth 1 -name "20061101-20131101_kh5x7tte9n_201_*" | wc -l
10000
real 0m0.034s
user 0m0.017s
sys 0m0.021s
$ time ls -1 | grep 20061101-20131101_kh5x7tte9n_201 | wc -l
10000
real 0m0.254s
user 0m0.245s
sys 0m0.020s
find
в 5 раз быстрее! Но если мы используем ls -1f
(спасибо еще раз Петеш!), То ls
даже быстрее, чем find
:
$ time ls -1f | grep 20061101-20131101_kh5x7tte9n_201 | wc -l
10000
real 0m0.023s
user 0m0.020s
sys 0m0.012s
Ответ 2
Попробуйте следующее:
ls -1 | grep 20061101-20131101_kh5x7tte9n_2010_ | wc -l
Ответ 3
у вас слишком длинный аргумент, потому что оболочка расширяет ваш шаблон до списка файлов.
попробуйте:
find -maxdepth 1 -name '20061101-20131101_kh5x7tte9n_2010_*' |wc -l
обратите внимание - шаблон заключен в кавычки, чтобы предотвратить расширение оболочки
Ответ 4
Как правило, следует избегать использования ls
в сценариях, и на самом деле выполнение вычислений в функции оболочки позволит избежать ошибки "слишком длинный список аргументов", поскольку границы exec
отсутствуют, и поэтому ограничение ARGV_MAX
не вступает в игру.
number_of_files () {
if [ -e "$1" ]; then
echo "$#"
else
echo 0
fi
}
Условное предохранение от глоба вообще не раскрывается (это стандартное значение по умолчанию; в Bash вы можете shopt -s nullglob
чтобы подстановочные знаки, не соответствующие ни одному файлу, были развернуты в пустую строку).
Попытайся:
number_of_files 20061101-20131101_kh5x7tte9n_2010_*
Ответ 5
ls -1 | grep '20061101-20131101_kh5x7tte9n_2010_*' | wc -l
Предыдущий ответ не включал цитаты вокруг критериев поиска ни * wildcard.