Я хочу выполнить поиск строки текста во всех файлах в каталоге (а не в его подкаталогах; я знаю, что -r опция делает это, но это не то, чего я хочу).
Бегущий
grep "string" /path/to/dir
предполагается, что я могу это сделать, я читал, но это выдает мне ошибку:
grep: dir: Это каталог
Затем я попробовал запустить grep на нескольких файлах.
grep "string" .bashrc .bash_aliases работает отлично.
grep "string" .bash* тоже работает по назначению.
grep "string" * выдает мне ошибки:
grep: data: Is a directorygrep: Desktop: Is a directorygrep: Documents: Is a directorygrep: Downloads: Is a directory...
Печатаются только ошибки, я не получаю совпадающих строк. Я попытался использовать -s вариант, но безрезультатно.
Итак, мои вопросы:
Почему я не могу использовать grep в каталоге, как в (1), когда я должен быть в состоянии? Я видел, как это делается во множестве примеров в Интернете. Редактировать: Когда я говорю "использование grep в каталоге", я имею в виду "поиск по всем файлам в этом каталоге, исключая его подкаталоги". Я полагаю, что это то, что делает grep, когда вы передаете ему каталог вместо файла. Я ошибаюсь?
Пожалуйста, дайте мне объяснение того, как работает grep это объяснило бы поведение команд в (2). Редактировать: Позвольте мне быть более конкретным. Почему использование подстановочных знаков для указания нескольких файлов для поиска для работы с .bash* и не с * или даже ./*?
Как я могу выполнить поиск по всем файлам в каталоге (а не в его подкаталогах) с помощью grep?
В Bash глобус не будет расширяться в скрытые файлы, поэтому, если вы хотите выполнить поиск все файлы в каталоге, вам нужно указать скрытые файлы .* и не скрытый *.
Чтобы избежать ошибок "Это каталог", вы могли бы использовать -d skip, но в моей системе я также получаю сообщение об ошибке grep: .gvfs: Permission denied†, поэтому я предлагаю использовать -s, который скрывает все сообщения об ошибках.
Итак, команда, которую вы ищете, - это:
grep -s "string" * .*
Если вы ищете файлы в другом каталоге:
grep -s "string" /path/to/dir/{*,.*}
Другим вариантом является использование dotglob опция оболочки, которая заставит глобус включать скрытые файлы.
shopt -s dotglobgrep -s "string" *
Для файлов в другом каталоге:
grep -s "string" /path/to/dir/*
† Кто-то упомянул, что я не должен получать эту ошибку. Возможно, они правы - я кое-что прочитал, но сам ничего не понял.
Grep выполняет поиск внутри файлов. Вы можете выполнять рекурсивный поиск, как вы сказали, если хотите искать файлы внутри каталога.
По умолчанию grep считывает все файлы и определяет каталоги. Поскольку по умолчанию вы не определили, что делать с каталогами с -d опция, она выдает вывод с ошибкой.
Поиск только в родительском каталоге будет grep -d skip "string" ./*
Таким образом, этот поиск по строке "ПУТЬ" со списком имен файлов под домашним каталогом пользователя выполняется только для файлов, начинающихся с точки.
/root/.bash_history/root/.bash_profilegrep: /root/.cache: Is a directorygrep: /root/.config: Is a directorygrep: /root/.dbus: Is a directory
Используя grep PATH ~/.[^.]* вы увидите все вхождения, включая строку с ключевым словом для поиска.
/root/.bash_history:echo $PATH/root/.bash_history:echo $PATH/root/.bash_history:PATH=$PATH:~/bin/root/.bash_history:echo $PATH/root/.bash_profile:PATH=$PATH:$HOME/bin/root/.bash_profile:export PATHgrep: /root/.cache: Is a directorygrep: /root/.config: Is a directorygrep: /root/.dbus: Is a directory
Чтобы избавиться от перенаправления ошибки в /dev/null, например
Таким образом, вы можете применить этот шаблон для поиска строки "Apache" в файлах из каталога /etc - поиск только в файлах ниже этого основного каталога. Вы видите, что это не возвращается из /etc/httpd/conf/httpd.conf
Кроме того, вы полагаетесь на расширяющиеся подстановочные знаки оболочки, такие как “*”, известные как глобализация. Глобализация не включает имена файлов, начинающиеся с точки, такие как .bashrc в качестве стандарта. Вы можете настроить параметры оболочки так, чтобы она включала эти файлы, но вы можете попасть в небольшую передрягу, если не знаете, что делаете. Хорошее руководство по пониманию глобализации можно найти здесь http://mywiki .wooledge.org/glob
Я не знаю почему, но я всегда делал глобализацию скрытых файлов, и это всегда срабатывало. Я не менял никаких настроек или что-то в этом роде. Как я указывал в (2), он также работает с grep "string" .bash*.
Извините, мой последний пример был неверным. Вы также можете выполнять поиск в скрытых файлах и подавлять “это каталог”, потому что Linux технически рассматривает каталоги как файлы другого типа. Тогда команда будет следующей: grep "string" * .* 2>/dev/null или grep -s "string" * .*