Как использовать grep на всех файлах нерекурсивно в каталоге?

Я хочу искать строку текста во всех файлах в каталоге (и не его подкаталоги; я знаю -r опция делает это, но это не то, что я хочу).

  1. Выполнение

    grep "string" /path/to/dir
    

    как предполагается, может сделать это, я читал, но это дает мне ошибку:

    grep: dir: каталог

  2. Затем, я пытался работать grep на нескольких файлах.

    grep "string" .bashrc .bash_aliases работы отлично.

    grep "string" .bash* работы, как предназначено также.

    grep "string" * дает мне ошибки:

    grep: data: Is a directory
    grep: Desktop: Is a directory
    grep: Documents: Is a directory
    grep: Downloads: Is a directory
    ...
    

Только ошибки печатаются, я не получаю согласующие отрезки длинной линии. Я пытался использовать -s опция, но напрасно.

Так, мои вопросы:

  1. Почему я не способен использовать grep на каталоге, как в (1), когда я должен смочь? Я видел что сделанный в большом количестве примеров в Интернете.
    Править: Когда я говорю "использование grep относительно каталога", я имею в виду "поиск во всех файлах в том каталоге, исключая его подкаталоги". Я полагаю, что это - то, что grep делает при передаче каталога ему вместо файла. Действительно ли я являюсь неправильным?

  2. Дайте мне объяснение на работах grep это объяснило бы поведение команд в (2).
    Править: Позвольте мне быть более конкретным. Почему делает подстановочные знаки использования для определения нескольких файлов для поиска в работу с .bash* а не с * или даже ./*?

  3. Как я могу искать все файлы в каталоге (и не его подкаталоги) использование grep?

33
задан 26 May 2016 в 04:45

6 ответов

В Bash шарик не расширится в скрытые файлы, поэтому если Вы захотите искать все файлы в каталоге, необходимо указать скрытые файлы .* и нескрытый *.

Избегать "-каталог" ошибки, Вы могли использовать -d skip, но в моей системе я также получаю ошибку grep: .gvfs: Permission denied, таким образом, я предлагаю использовать -s, который скрывает все сообщения об ошибках.

Таким образом, команда, которую Вы ищете:

grep -s "string" * .*

Если Вы ищете файлы в другом dir:

grep -s "string" /path/to/dir/{*,.*}

Другая опция состоит в том, чтобы использовать dotglob опция оболочки, которая заставит шарик включать скрытые файлы.

shopt -s dotglob
grep -s "string" *

Для файлов в другом dir:

grep -s "string" /path/to/dir/*

† Кто-то упомянул, что я не должен получать эту ошибку. Они могут быть правы - я сделал некоторое чтение, но не мог понять его сам.

39
ответ дан 23 November 2019 в 00:34

Вам нужно -d skip опция прибавлена.

  1. Grep ищет в файлах. Можно искать рекурсивно, как Вы сказали, если Вы хотите искать файлы в каталоге.

  2. По умолчанию grep считает все файлы, и он обнаруживает каталоги. Поскольку по умолчанию Вы не определили, что сделать с каталогами с -d опция, это дает вывод ошибок.

  3. Поиск только в рамках родительского каталога был бы 'grep-d пропуск "строка". /*

10
ответ дан 23 November 2019 в 00:34

Старые таймеры, вероятно, сделали бы это:

find . -type f -print0 | xargs -0 grep "string"
7
ответ дан 23 November 2019 в 00:34

Перефразирование - Вы хотите к grep файлы на одном уровне подкаталога, но не рекурсивно вызываете хотя все подподкаталоги?

grep forthis  *  */*

Или если Вы не хотите файлы в текущем каталоге

grep forthis  */*

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

grep forthis  .*/*    */*   

должен сделать то задание.

Существует также -maxdepth и -mindepth параметры ограничения, доступные find команда также.

2
ответ дан 23 November 2019 в 00:34

Вот пример для пропуска каталогов, не пропуская все ошибки:

grep --directories='skip' 'searchString' *
0
ответ дан 23 November 2019 в 00:34

Вы можете думать так, например, используя grep.

grep -l PATH ~/.[^.]*

Таким образом, этот поиск по строке «PATH» перечисляет имена файлов ниже домашнего каталога пользователя, только для файлов, которые начинаются с точки.

/root/.bash_history
/root/.bash_profile
grep: /root/.cache: Is a directory
grep: /root/.config: Is a directory
grep: /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 PATH
grep: /root/.cache: Is a directory
grep: /root/.config: Is a directory
grep: /root/.dbus: Is a directory

Чтобы избавиться от перенаправления ошибок, например, на /dev/null

grep PATH ~/.[^.]* 2>/dev/null

/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 PATH

Таким образом, вы можете применить этот шаблон для поиска строки «Apache» в файлах из каталога /etc, просматривая только файлы ниже этого основного каталога. Вы видите, что это не возвращается из /etc/httpd/conf/httpd.conf

grep Apache /etc/[^.]* 2>/dev/null
/etc/passwd:apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
/etc/services:derby-repli     4851/tcp                # Apache Derby Replication
/etc/services:derby-repli     4851/udp                # Apache Derby Replication
2
ответ дан 23 February 2020 в 21:20

Другие вопросы по тегам:

Похожие вопросы: