Как найти файл в файловой системе из командной строки?

10

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

В Windows я бы запустил следующее:

cd /d C:\
dir *filename* /s

Что такое эквивалент Linux?

Iszi
источник
Ну, есть совершенно очевидно, что есть несколько способов снять шкуру с этой кошки. Мне все еще немного любопытно узнать, есть ли способ сделать это ls?
Изи

Ответы:

13
locate filename
find -name '*filename*'
echo **/*filename*
ls -ld **/*filename*

(Ознакомьтесь с основными положениями и условиями. Прочтите руководство для мелкого шрифта.)

Перечисление содержимого каталога является своего рода вторичной функцией ls. Основная задача ls, которая занимает большую часть своей сложности, - это точная настройка дисплея. (Посмотрите руководство и сравните количество опций, связанных с выбором файлов для отображения, с количеством опций, которые определяют, какую информацию отображать о каждом файле и как форматируется отображение. Это верно как для GNU, так и для вас ». Я найду в Linux и других системах с меньшим количеством опций, начиная с первых дней.)

Режим по умолчанию ls- когда вы передаете ему каталог, он перечисляет файлы в этом каталоге. Если вы передадите ему файл любого другого типа (обычный файл, символическую ссылку и т. Д.), В нем будет указан только этот файл. (Это относится к каждому аргументу отдельно.) Опция -dзапрещает lsспускаться в каталог.

lsдействительно есть опция, -Rкоторая говорит ему о рекурсивном списке каталогов. Но он имеет ограниченную применимость и не позволяет много фильтровать на выходе.

Самый первый инструмент для сопоставления с образцом - это сама оболочка. Вам не нужны никакие другие команды: просто введите свои символы, и все готово. Это известно как глобус .

echo *filename*

Традиционно подстановочные знаки ограничивались текущим каталогом (или указанным каталогом:) echo /some/where/*filename*. A *соответствует любому имени файла или любой части имени файла, но *.txtне будет совпадать foo/bar.txt. Современные оболочки добавили шаблон, **/который означает «в этом каталоге или в любом каталоге под ним (рекурсивно)». В bash, по историческим причинам совместимости, эта функция должна быть явно включена с помощью shopt -s globstar(вы можете поместить эту строку в свой ~/.bashrc).

echo **/*filename*

Команда echoпросто выводит список имен файлов, сгенерированных оболочкой, обратно на вас. Как исключение, если нет подходящего имени файла вообще, шаблон подстановочного знака остается неизменным в bash (если только вы не установите shopt -s nullglob, в этом случае шаблон расширяется до пустого списка), и zsh выдает ошибку (если вы не установили setopt nullglob, или setopt no_no_matchчто приводит к тому, что шаблон остается неизменным).

Вы можете все еще хотеть использовать lsдля его вариантов. Например, lsможет давать указания о характере или правах доступа к файлу (каталог, исполняемый файл и т. Д.) С помощью цветов. Вы можете отобразить дату, размер и владельца файла с помощью ls -l. Смотрите руководство для многих других вариантов.

Традиционная команда ищет файл в дереве каталогов является find. Он имеет много опций для контроля, какие файлы отображать и что с ними делать. Например, чтобы найти файлы, чье имя соответствует шаблону *filename*в текущем каталоге и его подкаталогах, и напечатать их имена:

find /some/dir -name '*filename*' -print

-printявляется действием (большинство других действий состоит из выполнения команды над файлом); если не ставить в действие, -printподразумевается. Кроме того, если вы не указываете каталог для прохождения ( /some/dirвыше), подразумевается текущий каталог. Условие -name '*filename'предписывает перечислять (или действовать) только файлы, чье имя соответствует этому шаблону; Есть много других фильтров, таких как -mtime -1файлы, измененные за последние 24 часа. Иногда вы можете опустить кавычки -name '*filename*', но только если подстановочный знак не будет соответствовать ни одному файлу в текущем каталоге (см. Выше). В общем, краткая форма

find -name '*filename*'

Еще один полезный инструмент, когда вы знаете (часть) имя файла locate. Этот инструмент запрашивает базу данных имен файлов. В типичных системах он обновляется каждую ночь. Преимущество locateперед тем find /, что это намного быстрее. Недостатком является то, что его информация может быть устаревшей. Существует несколько реализаций, locateкоторые различаются по своему поведению в многопользовательских системах: базовая locateпрограмма индексирует только общедоступные файлы (вы можете захотеть запустить компаньон updatedbдля создания второй базы данных, которая индексирует все файлы в вашей учетной записи); Существуют другие версии (mlocate, slocate), которые индексируют все файлы и имеют locateпрограмму, фильтрующую базу данных, чтобы вернуть только те файлы, которые вы видите.

locate filename

Иногда вы думаете, что файл предоставляется пакетом в вашем дистрибутиве, вы знаете (часть) имя файла, но не имя вашего пакета, и вы хотите установить пакет. Многие дистрибутивы предоставляют инструмент для этого. На Ubuntu это так apt-file search filename. Для эквивалентных команд в других системах, проверьте Pacman Rosetta .

Жиль "ТАК - перестань быть злым"
источник
Хотел бы я снова проголосовать за это. Просто пришлось искать это для другого проекта сегодня вечером. Еще раз спасибо, @ Жиль!
Иззи
6

эквивалент вашего примера DOS будет:

cd /
find . -name \*filename\* -print

Однако в Linux вам больше не нужен -printаргумент. Если вы работаете с другими операционными системами, об этом может быть полезно знать.

Тим Кеннеди
источник
5

Если вы хотите что-то «быстрое» , но не в критической ситуации, и вам нужно только знать, существует ли оно и где оно, вы можете использовать locate. Он хранит базу данных всех файлов в каталогах, о которых вы сказали, для сбора информации.

При установке по умолчанию (в Ubuntu) locateнастраивается ежедневное cronзадание, которое сканирует файловую систему и обновляет базу данных ...

Если вы чувствуете, что вам нужно обновить базу данных до следующего обновления cron, обычно это быстрее, чем findили lsпросто запустить, sudo updatedbа затем locate. Это определенно быстрее, если вам нужно больше искать ... как следует из названия, updatedbобновляет базу данных, которая locateиспользует ...

locateимеет встроенное регулярное выражение, что делает его очень удобным ... Я буду использовать findв сценарии, но я редко использую findв командной строке. Я даже использую locateв (личных) сценариях ... например.locate -bir "oo.*datt.*mp4$"

locate возвращает полные пути сопоставленных файлов.

Peter.O
источник
2
find [path] -name [filename]

Например, если я хочу найти в каталоге / home имя файла, содержащего foo, я бы использовал команду:

find /home -name *foo*

используйте команду man findдля получения дополнительной информации о команде find и аргументах,

мистифицировать-Cain
источник
3
Вам нужно заключать в кавычки или экранировать *s, чтобы оболочка не интерпретировала их.
Шон Дж. Гофф
Это конкретный дистрибутив / оболочка? Я запустил его в Fedora 16 без побегов, и он работал нормально.
Джош-Каин
1
В некоторых оболочках есть опции, которые передают звезды в программу, если они ничего не соответствуют. Попробуйте создать файл в текущем каталоге, соответствующий этому шаблону, и повторите команду.
Шон Дж. Гофф