it-swarm-ru.tech

Как искать текст по всей файловой системе?

Предполагая, что следует использовать инструмент grep, я бы хотел найти текстовую строку "800x600" во всей файловой системе.

Я старался:

grep -r 800x600 /

но это не работает.

Я считаю, что моя команда должна делать рекурсивно grep через все файлы/папки в корневом каталоге для текста "800x600" и выводить результаты поиска.

Что я делаю неправильно?

56
Level1Coder

Обычно я использую этот стиль команды для запуска grep над несколькими файлами:

find / -xdev -type f -print0 | xargs -0 grep -H "800x600"

На самом деле это составляет список всех файлов в системе, а затем для каждого файла выполняет grep с заданными аргументами и именем каждого файла.

-xdev аргумент сообщает find, что он должен игнорировать другие файловые системы - это хорошо для того, чтобы избегать специальных файловых систем, таких как /proc. Однако он также будет игнорировать обычные файловые системы - поэтому, если, например, ваша папка/home находится в другом разделе, она не будет искать - вам нужно будет сказать find / /home -xdev ....

-type f означает поиск только по файлам, поэтому каталоги, устройства и другие специальные файлы игнорируются (он все равно будет возвращаться в каталоги и выполнять grep для файлов внутри - он просто не будет выполнять grep на самом каталоге, который не будет работать в любом случае). И -H опция grep говорит ему всегда печатать имя файла при выводе.

find принимает всевозможные опции для фильтрации списка файлов. Например, -name '*.txt' обрабатывает только файлы, заканчивающиеся на .txt. -size -2M означает файлы размером менее 2 мегабайт. -mtime -5 означает файлы, измененные за последние пять дней. Соедините их вместе с -a для и и -o для или и используйте '(' скобки ')' для группировки выражений (в кавычках, чтобы оболочка не могла их интерпретировать). Так, например:

find / -xdev '(' -type f -a -name '*.txt' -a -size -2M -a -mtime -5 ')' -print0 | xargs -0 grep -H "800x600"

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

68
Richard Downer

Обычно вы не захотите искать ВСЕ в системе. Linux использует файловые узлы для всего, поэтому некоторые "файлы" - это не те вещи, которые вы хотели бы искать. Например /dev/sda - это физическое блочное устройство для вашего первого жесткого диска. Вы, вероятно, хотите искать в смонтированных файловых системах, а не на сыром дисковом устройстве. Также есть /dev/random, который выдает случайные данные каждый раз, когда вы их читаете. Поиск, который не имеет большого смысла. /proc файловая система также проблематична в вашем случае.

Я бы порекомендовал одну из двух вещей.

  1. Не ищите в корне, ищите только места, которые могут быть полезны. Поиск /home или /usr или /etc отдельно Информация, которую вы ищете, скорее всего, относится к определенному типу, так что, скорее всего, она будет в определенной папке. Настройки конфигурации должны быть в /etc. Ваши личные данные должны быть в /home. Ограничение поиска основной областью, подобной этой, значительно уменьшит ваши проблемы с рекурсивными программами.

  2. Исключите проблемные области, используя --exclude-dir и ​​набор вещей, которые, как вы знаете, вам не нужны, вот так:
    grep -r --exclude-dir /proc --exclude-dir /dev --exclude-dir /tmp --exclude-dir /lost+found

Наконец, нередки случаи, когда при выполнении большого рекурсивного grep встречается несколько ошибок с отказом в разрешении. При обычном использовании есть файлы, которые ваш пользователь может не прочитать. Пока это всего лишь несколько нечетных файлов, а не такие вещи, как необработанное устройство для ваших жестких дисков или всей файловой системы proc, можно просто игнорировать ошибки. На самом деле вы можете сделать это в командной строке, отправив все ошибки никогда не приземляясь:

grep -r search_string /path 2> /dev/null
15
Caleb

Для простоты я бы предложил ack-grep . Ссылка показывает много случаев, когда ack-grep это лучший вариант.

Для использования есть, после установки:

ack-grep pattern /
3
bbaja42

Другой способ взглянуть на это так:

grep -r /* | grep "800x600"
2
maniat1k

* тогда я получаю/proc/sysrq-trigger: Ошибка ввода/вывода

Ваша команда работает, вы получаете эту ошибку, потому что вы пытаетесь сканировать запущенные процессы на наличие строки.

Я рекомендую исключить системные каталоги с

grep -exclude-dir = {proc, sys} "800x600" /

0
Koffee