Найти файлы по длине имени файла

Найти файлы по длине имени файла

Я хочу найти все файлы по длине имени файла.

Например, если я хочу найти файлы длиной 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

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