Как делают меня grep для нескольких шаблонов с шаблоном, имеющим символ вертикальной черты?

LVM является большим, но он работает лучше всего, когда у Вас есть большое свободное пространство, и можно создать небольшие логические тома, которые могут вырасти по мере необходимости.

Ваше предложенное расположение было бы, вероятно, прекрасно, но я сделаю отдельный / раздел начальной загрузки также. (Вы могли также сделать свой раздел подкачки меньшим. Вы никогда не хотите быть больше чем несколько ГБ в подкачку, так как производительность страдает плохо мимо этого. Плюс Вы может всегда добавлять файл подкачки, если Вы абсолютно имеете к.)

651
11.04.2018, 12:22
12 ответов

Во-первых, необходимо защитить шаблон от расширения оболочкой. Самый легкий способ сделать, который должен поместить одинарные кавычки вокруг этого. Одинарные кавычки предотвращают расширение чего-либо между ними (включая обратные косые черты); единственная вещь, которую Вы не можете сделать затем, имеют одинарные кавычки в шаблоне.

grep -- 'foo*' *.txt

(также отметьте -- end-of-option-marker для остановки некоторых grep реализации включая GNU grep от обработки названного файла -foo-.txt например (который был бы расширен оболочкой от *.txt) быть взятым в качестве опции (даже при том, что это следует за аргументом неопции здесь)).

При необходимости в одинарной кавычке можно записать это как '\'' (закончите строковый литерал, литеральную кавычку, открытый строковый литерал).

grep -- 'foo*'\''bar' *.txt

Во-вторых, grep поддерживает, по крайней мере, v два синтаксиса для шаблонов. Старый, синтаксис по умолчанию (основные регулярные выражения) не поддерживает чередование (|) оператор, хотя некоторые версии имеют его как расширение, но записанный с обратной косой чертой.

grep -- 'foo\|bar' *.txt

Портативный путь состоит в том, чтобы использовать более новый синтаксис, расширенные регулярные выражения. Необходимо передать -E опция к grep выбрать его (раньше, который был, покончили egrep разделите команду ²),

grep -E -- 'foo|bar' *.txt

Другая возможность, когда Вы просто ищете любой из нескольких шаблонов (в противоположность созданию сложного шаблона с помощью разъединения) состоит в том, чтобы передать несколько шаблонов grep. Можно сделать это путем предшествования каждому шаблону с -e опция.

grep -e foo -e bar -- *.txt

Или помещенные шаблоны на нескольких строках:

grep -- 'foo
bar' *.txt

Или сохраните те шаблоны в файле, один на строку и работайте

grep -f that-file -- *.txt

Отметьте это если *.txt расширяется до единственного файла, grep не снабдит префиксом согласующие отрезки длинной линии его имя как он, делает, когда существует больше чем один файл. Работать вокруг этого, с некоторыми grep реализации как GNU grep, можно использовать -H опция, или с любой реализацией, можно передать /dev/null как дополнительный аргумент.


¹ некоторые grep реализации поддерживают еще больше как perl-совместимые с -P, или увеличенные с -X, -K для ksh подстановочных знаков...

², в то время как egrep был удержан от использования POSIX и иногда больше не находится в некоторых системах, в некоторых других системах как Солярис, когда утилиты POSIX или GNU не были установлены, затем egrep Ваша единственная опция как /bin/grep поддержки ни один из -e, -f, -E, \| или многострочные шаблоны

897
27.01.2020, 19:27
  • 1
    Как заметка на полях - когда шаблоны фиксируются, необходимо действительно выработать привычку fgrep или grep -F, для маленьких шаблонов различие будет незначительно, но поскольку они становятся длиннее, преимущества начинают показывать... –  TC1 26.04.2012, 12:37
  • 2
    @TC1 fgrep ответа, удерживается от использования согласно странице справочника –  ramn 22.07.2014, 11:41
  • 3
    @TC1 Ли grep -F имеет фактический выигрыш в производительности, зависит от grep реализации: некоторые из них применяют тот же алгоритм так или иначе, так, чтобы -F имеет значение только ко времени, проведенному, анализируя шаблон а не ко времени, ища. GNU grep не быстрее с -F, например (это также имеет ошибку, которая делает grep -F медленнее в многобайтовых локалях — тот же постоянный шаблон с grep на самом деле значительно быстрее!). С другой стороны, BusyBox grep действительно извлекает выгоду много из -F на больших файлах. четкие указания –  Gilles 'SO- stop being evil' 22.07.2014, 11:53
  • 4
    Возможно, нужно упомянуть, что для более сложных шаблонов, где чередование только, чтобы быть для части регулярного выражения, оно может быть сгруппировано с "\(" и "\)" (выход для "основных регулярных выражений по умолчанию") (?). –  Peter Mortensen 20.05.2015, 12:45
  • 5
    Отметьте это egrep предшествует grep -E. Это не конкретный GNU (это, конечно, не имеет никакого отношения к Linux). На самом деле Вы все еще найдете системы как Солярис где значение по умолчанию grep все еще не поддерживает -E. –  Stéphane Chazelas 07.06.2016, 14:27

Во-первых, необходимо использовать кавычки для специальных символов. Во-вторых, несмотря на это, grep не поймет чередование непосредственно; необходимо было бы использовать egrep, или (с GNU grep только) grep -E.

egrep 'foo|bar' *.txt

(Круглые скобки являются ненужными, если чередование не является частью большего regex.)

17
27.01.2020, 19:27
  • 1
    На самом деле, grep -E является более стандартным, чем egrep. находка –  jw013 26.04.2012, 04:14

Как сказанная TC1, -F кажется, применимая опция:

$> cat text
some text
foo
another text
bar
end of file

$> patterns="foo
bar" 

$> grep -F "${patterns}" text
foo
bar
24
27.01.2020, 19:27
  • 1
    @poige я не знал о $ 'foo\nbar' опции, не уверенной, как расширение работает здесь, потребность искать, но поблагодарить Вас, который действительно полезен. –  haridsv 05.11.2012, 14:26
  • 2
    Хороший! Эта опция также, кажется, заставляет его работать намного быстрее (так как это отключает regex). –  qwertzguy 30.01.2018, 02:44
egrep "foo|bar" *.txt

или

grep "foo\|bar" *.txt
grep -E "foo|bar" *.txt

выборочно цитируя страницу справочника гну-grep:

   -E, --extended-regexp
          Interpret PATTERN as an extended regular expression (ERE, see below).  (-E is specified by POSIX.)

Matching Control
   -e PATTERN, --regexp=PATTERN
          Use PATTERN as the pattern.  This can be used to specify multiple search patterns, or to protect  a  pattern
          beginning with a hyphen (-).  (-e is specified by POSIX.)

(...)

   grep understands two different versions of regular expression syntax: “basic” and “extended.”  In  GNU grep,  there
   is  no  difference  in  available  functionality  using  either  syntax.   In  other implementations, basic regular
   expressions are less powerful.  The following description applies to extended regular expressions; differences  for
   basic regular expressions are summarized afterwards.

В начале я не читал далее, таким образом, я не распознал тонкие различия:

Basic vs Extended Regular Expressions
   In basic regular expressions the meta-characters ?, +, {, |, (, and ) lose their special meaning; instead  use  the
   backslashed versions \?, \+, \{, \|, \(, and \).

Я всегда использовал egrep и напрасно parens, потому что я извлек уроки из примеров. Теперь я изучил что-то новое.:)

103
27.01.2020, 19:27

У меня были журналы доступа, где даты были тупо отформатированы: [30 / июн / 2013: 08: 00: 45 +0200]

Но мне нужно было отобразить его как: 30 / июн / 2013 08:00:45

Проблема в том, что, используя «ИЛИ» в моем операторе grep, я получал два выражения соответствия в двух отдельных строках.

Вот решение:

grep -in myURL_of_interest  *access.log  | \
grep -Eo '(\b[[:digit:]]{2}/[[:upper:]][[:lower:]]{2}/[[:digit:]]{4}|[[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2}\b)'   \
| paste - - -d" " > MyAccess.log
3
27.01.2020, 19:27

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

root@gateway:/home/sshuser# aws ec2 describe-instances --instance-ids i-2db0459d |grep 'STATE\|TAG'

**STATE**   80      stopped

**STATE**REASON     Client.UserInitiatedShutdown    Client.UserInitiatedShutdown: User initiated shutdown

**TAGS**    Name    Magento-Testing root@gateway:/home/sshuser#
1
27.01.2020, 19:27

Если вам не нужны регулярные выражения, гораздо быстрее использовать fgrep или grep -F с несколько параметров -e, например:

fgrep -efoo -ebar *.txt

fgrep (альтернативно grep -F ) намного быстрее, чем обычный grep, потому что он ищет фиксированные строки вместо регулярных выражений.

8
27.01.2020, 19:27

Вы можете попробовать выполнить следующую команду для получения результата:

egrep 'rose.*lotus|lotus.*rose' some_file
6
27.01.2020, 19:27

Дешевый и удобный способ поиска нескольких шаблонов с помощью grep:

$ echo "foo" > ewq ; echo "bar" >> ewq ; grep -H -f ewq *.txt ; rm ewq
3
27.01.2020, 19:27

Это можно сделать несколькими способами.

  1. grep 'foo\|bar' *.txt
  2. egrep 'foo|bar' *.txt
  3. find. -maxdepth 1 -type f -name "*.txt" | xargs grep 'foo\|bar'
  4. find. -maxdepth 1 -type f -name "*.txt" | xargs egrep 'foo|bar'

3-й и 4-й варианты будут искать только в файлах и избегать каталогов, имеющих .txtв своих именах.
Итак, согласно вашему варианту использования -, вы можете использовать любой из вариантов, упомянутых выше.
Спасибо!!

1
27.01.2020, 19:27

TL;DR :если вы хотите сделать больше после сопоставления с одним из нескольких шаблонов, заключите их, как в\(pattern1\|pattern2\)

пример :Я хочу найти все места, где переменная, содержащая имя 'date', определяется как String или int. (например, "int cronDate =" или "String textFormattedDateStamp ="):

cat myfile | grep '\(int\|String\) [a-zA-Z_]*date[a-zA-Z_]* =' 

С grep -Eвам не нужно экранировать круглые скобки или вертикальную черту, т. е.grep -E '(int|String) [a-zA-Z_]*date[a-zA-Z_]* ='

4
27.01.2020, 19:27

, чтобы добавить к ответ @geekosaur , если у вас есть несколько шаблонов, которые также содержат вкладки и пробел, вы используете следующую команду

grep -E "foo[[:blank:]]|bar[[:blank:]]"

где [[:blank:]]— класс символов RE, представляющий либо пробел, либо символ табуляции

1
27.01.2020, 19:27

Теги

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