У меня проблемы с поиском по ВСЕМ каталогам одновременно с помощью grep . Когда я использую команду:

find . -name "*.txt" | xargs grep texthere

Это займет вечность, а затем выдаст мне ошибки "нет такого файла или каталога".

Почему это происходит и нет ничего проще, чем grep? Или я использую неправильную команду?

3 ответа3

1

Если у вас есть GNU grep, сама grep поддерживает опцию "-r" для рекурсивного поиска, как предлагает @Ouroborus.

Если, к сожалению, ваш grep не поддерживает такую опцию, как в SunOS, вы можете использовать следующие команды:

find . -name "*.txt" -exec grep -n your_pattern {} /dev/null \;

Хитрость добавлена в /dev/null чтобы гарантировать, что каждое выполнение grep имеет два предоставленных файла (файл соответствует * .txt и /dev /null), заставляя его печатать имя искомых файлов. И вы можете добавить опцию -type f для find чтобы уточнить область find .

0

Если вы получаете ошибки о разрешениях (вы не говорите, что делаете), то я предполагаю, что вы стоите либо в корневом каталоге (/), либо в каком-то пути, где у вас нет разрешения на чтение всех файлов Например, в /etc или в /var . Но поскольку вы говорите, что это занимает очень много времени, я больше склоняюсь к первому предположению (корневому каталогу).

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

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

На данный момент у вас есть

$ find . -name "*.txt" | xargs grep texthere

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

$ find / -type f \! -perm -o=x -name "*.txt" | xargs grep texthere

Я заменил . с / здесь, потому что я думаю, что вы здесь (поправьте меня, если я ошибаюсь). Я также указываю, что я хочу файлы (-type f), которые не являются исполняемыми (\! -perm -o=x) (! необходимо экранировать, чтобы ваша оболочка не делала с ним смешных вещей).

Теперь есть еще несколько вещей, которые мы можем сделать. Одним из них является безопасность вещь, а другой, возможно , улучшить скорость чуть - чуть.

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

$ find / -type f \! -perm -o=x -name "*.txt" -print0 | xargs -0 grep texthere

Это -print0 означает , что каждое имя файла будет ограничен в nul символ \0 , а не символ пробела. И соответствующая опция для xargs для получения их как nul -delimited имен файлов -0 .

Я полагаю, что из-за того, что вы не используете эти две опции, вы получаете эти ошибки "нет такого файла или каталога".

Скорость вещь fgrep . Это утилита, которая в точности эквивалентна grep -F которую вы должны использовать, если ваша строка поиска представляет собой текстовую строку без регулярных выражений.

Итак, если у вас есть простая текстовая строка, и вы хотите искать ее в каждом отдельном файле во всей системе:

$ find / -type f \! -perm -o=x -name "*.txt" -print0 | xargs -0 fgrep texthere

Вещь разрешения ... Очевидно, что будут файлы, которые вы не сможете прочитать. Вы можете либо запустить find и fgrep sudo к ним:

$ sudo find ... | xargs -0 sudo fgrep texthere

Или вы можете попытаться создать другой флаг -perm для find (а также заставить его игнорировать каталоги, в которые вы не можете войти), но это будет слишком много времени и приведет к смехотворно длинной командной строке, поэтому я не буду этого делать что здесь

Или вы могли бы просто sudo -s получить корневую оболочку и запустить ее оттуда ... но я бы вообще советовал против этого, потому что люди склонны портить свои системы, забывая, что они root .

ДРУГОЕ РЕШЕНИЕ будет использовать команду locate чтобы найти все .txt файлы во всей системе. Команда locate не ищет файловую иерархию, а использует базу данных (которая обычно обновляется ежедневно, поэтому там могут находиться не все файлы). База данных содержит только файлы в каталогах, доступных всем пользователям, поэтому, если вы удалили разрешения на чтение в своих собственных каталогах, ваши файлы там не будут.

Итак, заменив команду find выше на locate почти эквивалентную:

$ locate '*.txt' -0 | xargs -0 fgrep texthere

Опция -0 (или --null в некоторых системах) соответствует опции --print0 в find .

0

Как и в этом ответе, вам, вероятно, лучше:

grep -rnw '/path/to/somewhere/' -e "pattern"

  • -r или -R является рекурсивным,
  • -n это номер строки, и
  • -w стоит соответствует всему слову.
  • -l ( строчная буква L) может быть добавлена, чтобы просто дать имя файла совпадающих файлов.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .