Использование знака звездочки в grep


88

Я пытаюсь найти подстроку «abc» в конкретном файле в linux / bash

Итак, я делаю:

grep '*abc*' myFile

Он ничего не возвращает.

Но если я это сделаю:

grep 'abc' myFile

Он правильно возвращает совпадения.

Теперь для меня это не проблема. Но что, если я хочу найти более сложную строку, например

*abc * def *

Как мне это сделать с помощью grep?


3
Сам grep не поддерживает подстановочные знаки на большинстве платформ. Для использования подстановочных знаков необходимо использовать egrep. Оболочки имеют другой синтаксис. «*» в оболочке - это <любая строка>. В egrep это оператор, который говорит «0 многим из предыдущих объектов». В grep это обычный символ.
PanCrit 01

@PanCrit: *означает то же самое в grep и egrep: это квантификатор, означающий ноль или более предшествующих атомов. Это совершенно другая концепция, чем подстановочные знаки, используемые оболочкой.
Алан Мур

Ответы:


123

Звездочка - это просто оператор повторения , но вам нужно указать ему, что вы повторяете. /*abc*/соответствует строке, содержащей ab и ноль или более c (потому что вторая * находится на c; первая бессмысленна, потому что ей нечего повторять). Если вы хотите сопоставить что-либо, вам нужно сказать .*- точка означает любой символ (в рамках определенных правил ). Если вы хотите просто сопоставить abc, вы можете просто сказать grep 'abc' myFile. Для более сложного соответствия вам необходимо использовать .*- grep 'abc.*def' myFileбудет соответствовать строке, содержащей abc, за которой следует def с чем-то, необязательно между ними.

Обновление на основе комментария:

*в регулярном выражении не совсем то же самое, что * в консоли. В консоли * является частью конструкции glob и просто действует как подстановочный знак (например ls *.log, перечислит все файлы, которые заканчиваются на .log). Однако в регулярных выражениях * является модификатором, что означает, что он применяется только к предшествующему ему символу или группе. Если вы хотите, чтобы * в регулярных выражениях действовал как подстановочный знак, вам необходимо использовать, .*как упоминалось ранее: точка является подстановочным знаком, а звездочка при изменении точки означает поиск одной или нескольких точек; т.е. найти одного или нескольких персонажей.


1
Я думаю, что вопросник смущен различием между подстановочными знаками оболочки и регулярными выражениями. Я также подозреваю, что более сложным выражением было бы: grep 'abc. * Def' (присутствует хотя бы один пробел - возможно, два, как я писал).
Джонатан Леффлер,

1
На самом деле, похоже, спрашивающий не понимает, что «abc» - это не то же самое, что «^ abc $» :-D
Масса

1
Да, я запутался между glob и полными регулярными выражениями. Я использую * без точки, чтобы обозначить соответствие чему-либо в оболочке.
Saobi 01

1
grep *означает «0 или больше», а grep по умолчанию является жадным. Обратите внимание , что в Grep основных регулярных выражений метасимволы ?, +, {, |, (, и )теряют особый смысл. Более подробная информация: grep regexps
KrisWebDev

25

Точка означает совпадение с любым символом, т.е. .*означает ноль или более вхождений любого символа. Вы, вероятно, хотите использовать, .*а не просто *.


Точка - это метасимвол, который принимает любой символ, кроме новых строк .
Абхишек Камаль

12

«Знак зодиака» имеет значение, только если перед ним что-то есть. Если инструмента нет (в данном случае grep), это может просто обработать его как ошибку. Например:

'*xyz'    is meaningless
'a*xyz'   means zero or more occurrences of 'a' followed by xyz

5
* Не бессмысленно; это просто не имеет своего обычного значения (повторения), но означает «Я звезда». Он будет соответствовать строке, содержащей звезду, за которой следуют x, y и z.
Джонатан Леффлер,

2
@Jonathan Это зависит от инструмента.


6

Выражение, которое вы пробовали, как и те, которые работают, например, в командной строке оболочки в Linux, называется « glob ». Выражения Glob не являются полноценными регулярными выражениями , которые grep использует для указания строк, которые нужно искать. Вот (старый, небольшой) пост о различиях. Выражения glob (например, "ls *") интерпретируются самой оболочкой.

Переводить из глобусов в RE можно, но обычно это нужно делать в уме.


1
Это только глобус, если он разбирается оболочкой. Поскольку он сохраняет строку поиска внутри одинарных кавычек, оболочка оставляет строку в покое и передает ее в неизменном виде в argv в grep.
Conspicuous Compiler

4

Вы не используете регулярные выражения, поэтому вам следует выбрать вариант grep fgrep, который будет вести себя так, как вы ожидаете.


2
fgrepтеперь устарел, grep -fследует использовать вместо него.
Прометей

1
Это "grep -F". Старый добрый fgrep может быть "устаревшим", но они не собираются убирать его, пока я жив.
Эндрю Билс


1

Это может быть ответ, который вы ищете:

grep abc MyFile | grep def

Единственное, что ... он будет выводить строки, в которых "def" стоит перед OR после "abc"


1

Это сработало для меня:

grep ". * $ {expr}" - в двойных кавычках, которым предшествует точка. Где «expr» - это любая строка, которая вам нужна в конце строки.

Стандартный unix grep без дополнительных ключей.


0

'*' работает как модификатор для предыдущего элемента. Таким образом, "abc * def" ищет "ab", за которым следует 0 или более "c", за которыми следует "def".

Вам, вероятно, понадобится «abc. * Def», который ищет «abc», за которым следует любое количество символов, за которым следует «def».

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.