Я хочу найти все файлы по длине имени файла.
Например, если я хочу найти файлы длиной 1, такие как a.go
, b.go
.
Я кладу:
grep '.\{1\}' file
Но это не работает. Какую команду можно использовать для поиска файлов по длине имени файла?
решение1
Если вы просто хотите найти имена файлов, вы можете использовать следующую команду:
find -exec basename '{}' ';' | egrep '^.{100,}$'
Это запустит find
, вытащив имя файла или каталога с помощью basename
, а затем найдя любое имя файла или каталога, которое содержит не менее 100 символов. Если вы хотите найти имя файла точной длины, используйте {100}
вместо {100,}
.
Если вы хотите найти имена файлов, включая путь, сделайте следующее:
find | egrep '/[^/]{100,}$'
Это вернет имя файла, включая относительный путь к месту, где вы запустили команду find.
решение2
grep
ищет закономерности в содержимом файлов. Если вы хотите посмотреть наименафайлов, вы можете просто использовать shell-глоб (если вы хотите учитывать только имена файлов в текущем каталоге):
echo ?.go
(Кстати, именно оболочка оценивает глоб, а не echo
команда.)
Если вы хотите просмотреть каталоги рекурсивно, начиная с текущего каталога, используйте следующий инструмент find
:
find . -name '?.go'
(Обратите внимание, что вам необходимо заключить шаблон в кавычки, чтобы оболочка не оценила его как шаблон перед find
вызовом.)
решение3
Прежде всего, grep
поиск посодержаниефайлов, он не будет искать имена файлов. Для этого вам нужно find
. У него нет возможности задать длину имени файла, но вы можете проанализировать его вывод, чтобы получить то, что вам нужно. Вот несколько примеров, которые я запускаю в каталоге, содержащем следующие файлы:
$ tree
.
├── a
├── ab
├── abc
├── abcd
└── dir
├── a
├── ab
├── abc
└── abcd
Поиск файлов в этом каталоге возвращает:
$ find . -type f | sort
./a
./ab
./abc
./abcd
./dir/a
./dir/ab
./dir/abc
./dir/abcd
Итак, чтобы найти файлы длиной X, нам нужно будет удалить путь и сопоставить только символы после последнего /
:
$ find . -type f | grep -P '/.{3}$'
Команда sed
просто удаляет ./
. -P
Флаг активирует Perl-совместимые регулярные выражения, которые необходимы для {n}
того, что является вещью PCRE и $
означает «соответствие концу строки».
Вы также можете просто сделать это:
find . -type f | grep -P '/...$'
Это нормально для небольших чисел, но ввод 15 точек для соответствия именам файлов длиной 15 не очень эффективен.
Наконец, если вы хотите игнорировать расширение и искать только по имени файла, сделайте следующее (как предложил @slm):
find . -type f | grep -P '/.{1}\.'
Однако это также найдет файлы типа a.bo.go
. Это лучше, если ваши имена файлов могут содержать более одного .
:
find . -type f | grep -P '/.{1}\.[^.]+$'
ПРИМЕЧАНИЕ: Решение выше предполагает, что у вас относительно разумные имена файлов, которые не содержат символы новой строки и т. д. Оно также будет учитывать, а не игнорировать пробелы в именах файлов при расчете длины, что может быть не тем, что вам нужно. Если что-то из этого является проблемой, дайте мне знать, и я обновлю свой ответ.
решение4
Вы не указываете, но если файлы находятся в структуре каталогов, вы можете использовать ее find
для поиска файлов длиной 1 с помощью grep
:
$ find . -type f | grep -P '/.{1}\.'
Пример
$ find . -type f | grep -P '/.{1}\.' | head -10
./util-linux-2.19/include/c.h
./88366/a.bash
./89186/a.bash
./89563/b.txt
./89563/a.txt
./89563/c.txt
./89563/d.txt
./91734/2.c
./91734/4.c
./91734/1.c