Я хочу найти строку текста во всех файлах в каталоге (а не в его подкаталогах; я знаю, что -r
опция делает это, но это не то, что я хочу).
Бег
grep "string" /path/to/dir
я должен был это сделать, я читал, но это дает мне ошибку:
grep: dir: это каталог
Затем я попытался запустить
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
опцию, но безрезультатно.
Итак, мои вопросы:
Почему я не могу использовать
grep
каталог, как в (1), когда я должен это сделать? Я видел это в большом количестве примеров в Интернете.
Редактировать : когда я говорю «использование grep в каталоге», я имею в виду «поиск во всех файлах в этом каталоге, за исключением его подкаталогов». Я считаю, что это то, что делает grep, когда вы передаете ему каталог вместо файла. Я не прав?Пожалуйста, дайте мне объяснение о том, как
grep
это могло бы объяснить поведение команд в (2).
Изменить : Позвольте мне быть более конкретным. Почему использование подстановочных знаков для указания нескольких файлов для поиска для работы,.bash*
а не с*
или даже./*
?Как я могу найти все файлы в каталоге (а не в его подкаталогах), используя
grep
?
*
, называемые globbing. Глобирование не включает имена файлов, начинающиеся с точки, такой.bashrc
как стандарт. Вы можете установить параметры оболочки так, чтобы она включала эти файлы, но вы можете немного запутаться, если не знаете, что делаете. Хорошее руководство по пониманию глобинга можно найти здесь mywiki.wooledge.org/globgrep "string" .bash*
тоже работает .grep "string" * .* 2>/dev/null
илиgrep -s "string" * .*
Ответы:
В Bash глобус не будет расширяться до скрытых файлов, поэтому, если вы хотите искать все файлы в каталоге, вам нужно указать скрытые
.*
и не скрытые файлы*
.Чтобы избежать ошибок «Является ли каталог», вы могли бы использовать
-d skip
, но в моей системе я также получаю ошибкуgrep: .gvfs: Permission denied
† , поэтому я предлагаю использовать-s
, которая скрывает все сообщения об ошибках.Итак, команда, которую вы ищете:
Если вы ищете файлы в другом каталоге:
Другим вариантом является использование параметра
dotglob
оболочки, который будет включать в себя скрытые файлы.Для файлов в другом каталоге:
† Кто-то упомянул, что я не должен получать эту ошибку. Возможно, они правы - я немного почитал, но сам не мог понять, что с ним делать.
источник
*
и.*
?echo * .*
иecho *.*
запустите в вашем домашнем каталоге, и разница должна быть очевидной. Иначе ЛМК и я это объясню.echo *
показывает не скрытые файлы и папки,echo *.*
показывает не скрытые файлы,echo .*
показывает все файлы иecho * .*
показывает все файлы и каталоги. Но почему причина пространства между двумя в последнем случае? Мне это кажется грязным. Разве нет способа объединить два, чтобы получить одинаковые результаты? Или в противном случае есть синтаксическое объяснение, почему эти два должны быть разделены здесь, или* .*
это исключительный случай?*
представляет все не скрытые файлы (т.е. имена файлов, которые не начинаются с точки);.*
представляет все скрытые файлы (т.е. имена файлов , которые действительно начинаются с точкой); и*.*
представляет все не скрытые файлы, которые содержат точку. Вecho * .*
этом случае два глоба должны быть разделены, потому что это разные глобусы: один для скрытого, другой для скрытого. Хотя, как я написал в своем ответе, вы можете*
включить скрытые файлы, включивdotglob
опцию оболочки.*.*
в Windows (DOS) для вывода списка всех файлов, но в * nix будут включаться только файлы с точкой, поэтому в * nix это не имеет смысла. Вместо этого вы используете*
список всех файлов, кроме скрытых, и.*
список скрытых файлов.Вам нужно
-d skip
добавить опцию.Grep ищет внутри файлов. Как вы сказали, вы можете искать рекурсивно, если вы хотите искать файлы внутри каталога.
По умолчанию grep прочитает все файлы и обнаружит каталоги. Поскольку по умолчанию вы не определили, что делать с каталогами с помощью
-d
опции, она выдаст ошибку.Поиск только в родительском каталоге будет
grep -d skip "string" ./*
источник
man grep
.-d skip
не работает; это в основном так же, как-s
; также см. редактирование. (с) Нет,grep -d skip "string" ./*
тоже не работает.Старые таймеры, вероятно, сделали бы это:
источник
find . -type f -exec grep string {} +
?-maxdepth 1
.find . -type f -maxdepth 1 -exec grep string /dev/null {} +
-H
к grep.Перефразируя - вы хотите grep файлы в одном уровне подкаталога, но не повторять через все подкаталоги?
Или, если вы не хотите файлы в текущем каталоге
Обратите внимание, что каталоги не будут начинаться с точки.
должен сделать эту работу.
Там также
-maxdepth
и-mindepth
параметры доступны ограничение наfind
команды тоже.источник
grep forthis */*
искать файлы как в текущем каталоге, так и в одном из них?*/*
сопоставляет только одну косую черту. Если у вас есть файл с именемa/b
в текущем каталоге, то `* / * будет соответствовать этому.Вот пример, чтобы пропустить каталоги, не пропуская все ошибки:
источник