Найти все файлы с именем, содержащим строку


177

Я искал команду, которая будет возвращать файлы из текущего каталога, которые содержат строку в имени файла. Я видел locateи findкоманды, которые могут найти файлы, начинающиеся с чего-то first_word*или заканчивающиеся чем-то *.jpg.

Как я могу вернуть список файлов, которые содержат строку в имени файла?

Например, если 2012-06-04-touch-multiple-files-in-linux.markdownбыл файл в текущем каталоге.

Как я могу вернуть этот файл и другие, содержащие строку touch? Использование команды, такой какfind '/touch/'


вопрос сбивает с толку. Вы хотите найти файлы, которые содержат строку, или файлы, имена которых содержат указанную строку? на первый вопрос дан ответ man grep, на второй - man find. почему вы гуглите вместо того, чтобы использовать человека, я не знаю.
просто кто-то

1
Спасибо! В первом предложении не указано, является ли это содержимым файла или именем файла. Обновлено.
Дру

Ответы:


304

Используйте find:

find . -maxdepth 1 -name "*string*" -print

Он найдет все файлы в текущем каталоге (удалите, maxdepth 1если вы хотите, чтобы он был рекурсивным), содержащий «строку», и выведет его на экран.

Если вы хотите избежать файла, содержащего ':', вы можете ввести:

find . -maxdepth 1 -name "*string*" ! -name "*:*" -print

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

ls | grep touch

Но, повторяю, findэто лучшее и более чистое решение для вашей задачи.


Спасибо @Zagorax. Это делает это точно. Жаль, что команда была не так долго, но да :)
Dru

2
@Dru, Модифицированный, чтобы покрыть случай, если вы хотите избежать двоеточий. findэто очень мощный инструмент, он должен быть каким-то «длинным». :)
Zagorax

Спасибо, первый сделал это отлично, не возвращая никакого контента.
Дру

3
@Dru, если вы хотите, чтобы он был «короче», вы можете избежать, так -printкак это поведение по умолчанию и так .как это папка по умолчанию, где он проверяет.
Загоракс

1
find . -name "*string*"Отлично работает тоже. Удаление .выдает ошибку на моем конце. Еще раз спасибо @Zagorax.
Дру

14

Используйте grep следующим образом:

grep -R "touch" .

-Rзначит рекурсировать. Если вы не хотите заходить в подкаталоги, пропустите его.

-iозначает «игнорировать регистр». Вы также можете попробовать это.


Отлично. Я заметил, что некоторые файлы следуют за :. Есть ли какой-нибудь способ удержать это? Использование опции возможно?
Дру

1
Попробуйте:grep -R "touch" . | cut -d ":" -f 2
Carlspring

Это, кажется, производит только содержимое файлов. Вы, по сути, ответили на мой вопрос, хотя я могу попытаться покопаться, чтобы скрыть содержание.
Дру

Ах ... вам нужны только имена файлов? Беги: grep -R "touch" . | cut -d ":" -f 1 (прости, должно быть, неправильно понял тебя).
Carlspring

Спасибо @carlspring, это интересно. grepлибо возвращает файлы с содержимым и именами файлов, содержащими, touchлибо содержимым, содержащим touch, я не уверен, что это так, пока. Из возвращенного списка файлов половина содержит touchзаголовок, а другая половина содержит текст touch, а не заголовок. Просто понял это.
Дру

5

-maxdepthОпция должна быть перед -nameопцией, как показано ниже.,

find . -maxdepth 1 -name "string" -print

1
Вы должны поставить * до и после "строки".
Аэрин

3
find $HOME -name "hello.c" -print

Это будет искать во всей $HOME(то есть /home/username/) системе любые файлы с именем «hello.c» и отображать их пути:

/Users/user/Downloads/hello.c
/Users/user/hello.c

Тем не менее, это не будет соответствовать HELLO.Cили HellO.C. Для сопоставления без учета регистра передайте -inameпараметр следующим образом:

find $HOME -iname "hello.c" -print

Пример выходов:

/Users/user/Downloads/hello.c
/Users/user/Downloads/Y/Hello.C
/Users/user/Downloads/Z/HELLO.c
/Users/user/hello.c

Передайте -type fопцию только для поиска файлов:

find /dir/to/search -type f -iname "fooBar.conf.sample" -print
find $HOME -type f -iname "fooBar.conf.sample" -print

-inameРаботает либо на GNU или BSD (включая OS X) команду версии поиска. Если ваша версия команды find не поддерживает -iname, попробуйте следующий синтаксис с помощью grepкоманды:

find $HOME | grep -i "hello.c"
find $HOME -name "*" -print | grep -i "hello.c"

ИЛИ попробуйте

find $HOME -name '[hH][eE][lL][lL][oO].[cC]' -print

Пример выходов:

/Users/user/Downloads/Z/HELLO.C
/Users/user/Downloads/Z/HEllO.c
/Users/user/Downloads/hello.c
/Users/user/hello.c

0

Если строка находится в начале имени, вы можете сделать это

$ compgen -f .bash
.bashrc
.bash_profile
.bash_prompt

3
compgenне подходит молоток для этого ногтя. Этот малоиспользуемый инструмент предназначен для вывода списка доступных команд и, как таковой, он перечисляет файлы в текущем каталоге (которые могут быть скриптами) и не может ни просматривать, ни просматривать начало имени файла, ни искать содержимое файла, что делает его в основном бесполезно.
Мсанфорд

0

Альтернативой многим уже предоставленным решениям является использование глобуса **. Когда вы используете bashс опцией globstar(shopt -s globstar ) или используете zsh, вы можете просто использовать глобус **для этого.

**/bar

выполняет рекурсивный поиск в каталоге для файлов с именем bar (возможно, включая файл barв текущем каталоге). Обратите внимание, что это не может быть объединено с другими формами смещений в пределах того же сегмента пути; в этом случае* операторы возвращаются к своему обычному эффекту.

Обратите внимание, что есть небольшая разница между zshи bashздесь. Пока bashбуду перебирать софт-ссылки на каталоги, zshне буду. Для этого вы должны использовать шар ***/в zsh.



-2
grep -R "somestring" | cut -d ":" -f 1

2
Похоже, что это ответ на другой вопрос - но поскольку вы не предоставили объяснения, это не очевидно для спрашивающего или кого-либо еще.
Тоби Спейт
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.