Поиск файлов по длине имени файла


10

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

Например , если я хочу найти файлы длиной 1, например a.go, b.go.

Я кладу:

grep '.\{1\}' file

Но это не работает. Какую команду можно использовать для поиска файлов по длине имени файла?


a.goэто имя файла длины 4. aэто имя файла длины 1. Это Unix, а не DOS, где имя и расширение были отдельными и неявное .всегда было частью имени файла.
Питер Кордес

Ответы:


3

grepищет шаблоны в содержимом файлов. Если вы хотите посмотреть на имена файлов, вы можете просто использовать глобус оболочки (если вы хотите учитывать только имена файлов в текущем каталоге):

echo ?.go

(Кстати, это оболочка, которая оценивает глоб, а не echoкоманда.)

Если вы хотите просматривать каталоги рекурсивно, начиная с текущего каталога, используйте инструмент find:

find . -name '?.go'

(Обратите внимание, что вы должны заключить шаблон в кавычки, чтобы оболочка не оценивала его как глобус, прежде чем findего вызовут.)


1
Также будут найдены каталоги, которые также соответствуют шаблону «? .Go».
SLM

@slm, каталоги - это один из многих типов файлов, ОП не указал, какой тип файлов ему нужен.
Стефан Шазелас

8

Если вы просто хотите найти имена файлов, вы можете использовать следующую команду:

find -exec basename '{}' ';' | egrep '^.{100,}$'

Это запустится find, вытягивая имя файла или каталога, используя, basenameа затем ищите любое имя файла или имя каталога, которое содержит не менее 100 символов. Если вы хотите найти имя файла точной длины, используйте {100}вместо {100,}.

Если вы хотите найти имена файлов, включая путь, сделайте это:

find | egrep '/[^/]{100,}$'

Это вернет имя файла, включая относительный путь, по которому вы запустили команду поиска.


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}\.[^.]+$'

ПРИМЕЧАНИЕ. Приведенное выше решение предполагает, что у вас есть относительно нормальные имена файлов, которые не содержат символов новой строки и т. Д. Он также будет учитывать не игнорировать пробелы в именах файлов при расчете длины, которая может не соответствовать вашей. Если что-то из этого является проблемой, дайте мне знать, и я обновлю свой ответ.


1

Вы не указываете, но если файлы находятся в структуре каталогов, вы можете использовать, 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

В MacOS X используйте egrep и удалите опцию -P
Барт Куммель

@BartKummel - на самом деле на OSX я использую ggrep: heystephenwood.com/2013/09/install-gnu-grep-on-mac-osx.html . Также поймите, что этот Q не был помечен как OSX, так что использование grepявляется подходящим.
SLM

1

Я бы использовал что-то вроде этого.

find . -type f -name "?.go"

Так что, если вы поставите два "?" Затем вы ищете имена файлов с двумя символами и расширением.


0

Если вы хотите использовать регулярные выражения в команде find, вы должны использовать ""такие как:

find /var/log -iname "*.err" 

для вашего случая использования:

find yourpath -type f -a -name "?.go"

Вы должны заменить свой реальный путь на ваш путь, -aчто And -type fозначает, что вы ищете только обычные файлы.

? в вашем запросе имеется в виду один символ, такой как DOS, если вы помните.


-1

ls ?.* должен дать вам желаемые результаты.


добро пожаловать в Unix.SE. К сожалению, бесполезно добавлять ответы на старые вопросы, на которые уже есть много хороших ответов. (Если нет нового лучшего способа решения старой проблемы или у вас нет лучшего решения, чем любой из старых ответов.) Если вы хотите ответить на некоторые вопросы, посмотрите новые вопросы на первой странице.
Питер Кордес
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.