Различие в двух типах команды, которая использует grep

Так, здесь у нас есть две команды:

cat /var/log/dpkg.log | grep " \install\ "
cat /var/log/dpkg.log | grep install

Почему отличаются выводы этих команд? И можно ли объяснить первую команду немного.Заранее спасибо.

5
задан 22 December 2015 в 06:42

3 ответа

Первая часть Ваших двух команд (cat FILENAME) всегда то же и просто печатает содержание указанного файла к потоку STDOUT. Я не объясню это дальше.

Точка нашего интереса grep часть.

Синтаксис grep:

grep [OPTIONS] PATTERN [FILE...]

Можно передать grep некоторые опции настроить его поведение (например, установить используемый аромат RegEx или управлять выходным форматированием), но они не используются в Вашем случае.

Следующий отдельный аргумент должен быть шаблоном для соответствия, где регулярное выражение ("RegEx") или фиксированная строка (если grep назван с -F опция), требуется. В Вашем примере это install или "\ install\ " часть. Я объясню это в следующем абзаце.

После этого Вы указываете источник данных для соответствия. Это может или быть именем файла или ничем. Во втором случае, grep будет читать из потока STDIN (стандартный вход: обычно, что Вы вводите с клавиатурой), где Вы передаете по каналу (|) вывод от предыдущей команды.

Как правильно передать аргумент "ШАБЛОНА"?

Параметр шаблона должен быть отдельным аргументом. Это означает, Вы не можете только передать несколько слов или что-либо содержащее пробелы или окружить специальные символы здесь, потому что пробелы рассматривают как разделители аргумента в Bash и вероятно любой оболочке также, и окружают специальные символы такой как ; повредит команду.

Но у Вас есть две опции включать пробелы в шаблон для соответствия так или иначе:

  • Поместите всю строку для соответствия в единственном ('...') или дважды ("...") кавычки. Таким образом, оболочка анализирует всю включенную в кавычки строку как один аргумент и передает его на grep.

  • Выйдите из каждого пространства в шаблоне с обратной косой чертой (\). Это означает, Вы пишете обратную косую черту перед каждым пространством, которое Вы не хотите рассматриваться как разделитель аргумента оболочкой. Но обратите внимание, что, если Вы хотите иметь фактическую обратную косую черту в шаблоне, необходимо выйти из него также путем записи другой обратной косой черты перед ним.

Если мы теперь анализируем различие Ваших двух grep примеры команды, мы видим различие в том, чему они соответствуют:

cat /var/log/dpkg.log | grep "\ install\ "

Это соответствует шаблону install. (Отметьте продвижение и конечный пробел!)

Здесь мы видим оба метода: двойные кавычки вокруг всего шаблона и выхода обратной косой черты пробелы в нем. Это является лишним честно говоря, можно было бы быть достаточно. Хотя это не причиняет боль в этом случае, Вы не должны делать этого и выбирать один метод. Обычно я рекомендовал бы использовать кавычки, поскольку легче читать.

cat /var/log/dpkg.log | grep install

Это соответствует шаблону install. (Никакие окружающие пробелы.)

Здесь шаблон только состоит из слова install, ничто иное. Никакие пробелы.

Различие между Вашими командами:

Как я сказал, первый из Ваших примеров только распознает слово install когда это окружается пробелами. Это не соответствовало бы, если, например, существует точка или какой-либо другой символ непосредственно прежде или после него вместо этого. Это также не распознало бы слово непосредственно вначале или конец строки.

Второй пример не заботится ни о каких пробелах прежде или после слова install. Это также соответствует в начале строки и окончаниях, а также если это окружается пунктуацией. Это даже соответствует, если существует слово, содержащее эту последовательность буквы где-нибудь, например, "удаление", "переустановите" или "установка" также!

Пример с корректным/полезным выходом обратной косой черты:

Как в примере Вы, если обратные косые черты являются лишними, здесь тот же пример без кавычек, но с обратной косой чертой, выходящей только вместо этого:

cat /var/log/dpkg.log | grep \ install\ 

Или если Вы хотите соответствовать строке, "Мне нравится Ubuntu" в файле /home/you/path with spaces/textfile не используя кавычки, Вы сделали бы это как это:

grep I\ like\ Ubuntu /home/you/path\ with\ spaces/textfile

Вы видите, что необходимо выйти из пробелов в пути - или имена файлов также - или заключить им в кавычки. Строка выше равна строке ниже:

grep "I like Ubuntu" "/home/you/path with spaces/textfile"
8
ответ дан 23 November 2019 в 08:42

Вторая (более простая) форма будет соответствовать заданной строке в любом месте строки: например, она будет соответствовать строкам, подобным install ation, re install , install и т. Д.

Первое выражение будет соответствовать install только там, где на каждом конце есть пробел. Обратная косая черта - это что-то вроде красной сельди, так как кавычек уже достаточно (и первая - без надобности - экранирует i, а не пробел): однако она могла бы быть написана с использованием , только экранированных слов обратной

cat /var/log/dpkg.log | grep \ install\ 

(NB, в конце вышеуказанной команды есть буквальный пробел).


Добавление одного пробела в шаблон - это немного хак, ИМХО: он не будет работать, если шаблон отделен другим пробелом (табуляцией или окончанием строки). Лучшим вариантом может быть использование явных границ слов, например

grep '\binstall\b' /var/log/dpkg.log

или используйте переключатель -w (--word-regexp)

grep -w 'install' /var/log/dpkg.log

(хотя они включают дефисы и пробелы - так что эквивалентность не точна). Если вы действительно хотите получить экземпляры шаблона, разделенные пробелами, то вы можете использовать класс символов [[:space:]] POSIX, например

grep '[[:space:]]install[[:space:]]' /var/log/dpkg.log
4
ответ дан 23 November 2019 в 08:42

Первая команда:

cat /var/log/dpkg.log | grep " \install\ "

Как указывало @ByteCommander, возможна опечатка, и команда должна быть

cat /var/log/dpkg.log | grep "\ install\ "

Это будет соответствовать строке install с конечным и начальным пробелом. Этого также можно достичь с помощью grep -w "install". Кроме того, \ не требуется, когда вы используете кавычки.

Вторая команда:

cat /var/log/dpkg.log | grep install

Эта команда также соответствует строкам, содержащим install. Например, « установить ред».


Тестовый пример:
содержимое тестового файла:

foo
bar
foobar
foo bar

Выполнение:

cat file1.txt | grep foo
foo
foobar
foo bar

cat file1.txt | grep -w foo
foo
foo bar

cat file1.txt | grep "foo "
foo bar
3
ответ дан 23 November 2019 в 08:42

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

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