Как найти строки, начинающиеся с **

8

Мне нужно найти, если какие-либо строки в файле начинаются с **.

Я не могу понять, как это сделать, потому что *интерпретируется оболочкой как подстановочный знак.

grep -i "^2" test.out

работает, если строка начинается с 2, но

grep -i "^**" test.out 

очевидно не работает.

(Мне также нужно знать, заканчивается ли эта строка символом a, )но еще не пытался это сделать).

Шар хантер
источник

Ответы:

18

Используйте \символ для выхода из *, чтобы сделать его нормальным персонажем.

grep '^\*\*' test.out

Также обратите внимание на одинарную кавычку, 'а не двойную, "чтобы предотвратить расширение оболочки

Стивен Харрис
источник
3
Первый *не нужно бежать в данном конкретном случае, FWIW.
don_crissti
5
Хотя его не нужно избегать, отказ от первой звездочки будет более запутанным для случайного наблюдателя, как если бы вы подходили к «любому числу начала строк, за которым следует звездочка». Все, что делает регулярное выражение более понятным для сопровождающего, является хорошей идеей. =)
Заметный компилятор
1
Использование двойных кавычек также предотвратит расширение, а не только одинарные. Неправильный совет здесь.
rems4e
@ rems4e использование двойных кавычек будет препятствовать тому, чтобы оболочка расширяла звездочки, но не интерпретировала обратную косую черту. С двойными кавычками вам придется использовать grep "^\\*\\*"так, чтобы grep получал нужную ^\*\*строку, чтобы избежать интерпретации звездочек как квантификаторов регулярных выражений.
Аарон
7

Как вы хотели проверить строку, которая начинается **и заканчивается ), вы можете объединить две grepоперации, как это,

grep '^*\*' test.out | grep ')$'

Или с помощью одной grepкоманды, как это,

grep -E '^\*\*.*\)$' test.out

объяснение

  • ^\*\* : линия совпадения, которая начинается с **
  • .* : соответствовать всему после **
  • \)$: строка соответствия, которая также имеет )в конце строки.
Рахул
источник
3

Это не оболочка

Ни один из ответов до сих пор не коснулся настоящей проблемы. Было бы полезно объяснить, почему это не работает так, как вы ожидаете.

grep -i "^**" test.out

Поскольку вы процитировали шаблон для grep , *он не раскрывается оболочкой. Он передается в grep как есть. Это объясняется на странице руководства [1] для bash [2] :

Заключение символов в двойные кавычки сохраняет буквальное значение всех символов в кавычках, за исключением $, `, \ и, когда расширение истории включено,!.

Это обычные регулярные выражения

Регулярное выражение - это шаблон, который описывает набор строк.

*является одним из ключевых шаблонов в регулярных выражениях. По умолчанию grep интерпретирует это следующим образом:

* The preceding item will be matched zero or more times.

Это означает, что ваш шаблон в его нынешнем виде ^**не имеет особого смысла. Возможно, он пытается найти начало строки ноль или более раз , дважды. Что бы это ни значило.

Решение состоит в том, чтобы процитировать это:

Любой метасимвол со специальным значением может быть заключен в кавычки, если ему предшествует обратная косая черта.

grep -i "^\*\*" test.out


[1] Я не рекомендую читать это. Пожалуйста, используйте man dashили аналогичные.

[2] Оболочки не было дано, поэтому я предполагаю, что bash .

труба
источник
2

Другие опции.

Вы можете использовать sedили awkтакже

$ sed -n '/^*\*/p' test.out
$ awk '/^*\*/' test.out

Чтобы узнать строки, которые заканчиваются )использованием также grepили sedилиawk

$ grep ')$' test.out
$ sed -n '/)$/p' test.out
$ awk '/)$/' test.out
tachomi
источник
Спасибо всем ! Я действительно ценю помощь в этом!
Шар Хантер
1
И объединенная линия awk: '/^*\*/&&/)$/'...
jasonwryan
0

Это совершенно не цитируемая версия grep ^\\*\\* test.out. Чтобы передать буквенный обратный слеш из оболочки в grep, его необходимо экранировать.

Это работает, пока у вас нет файлов в каталоге, начиная с ^\другой обратной косой черты.

Бить Болли
источник