Intereting Posts
Как отправить байт как мутированный ввод в файл в Ubuntu Как правильно вызвать motd для соединений SSH с отключенным PAM Как настроить скрипт cryptroot? Как передать сложные команды оболочки через SSH для удаленного запуска? Ошибки синтаксиса выдачи шахт или интерпретировать локально! Как настроить SSH так, чтобы он ограничивался моей локальной сетью? Нет видимого экрана после обновления до 11.10, загрузка системы в tty1 Статическое расположение диска CD / DVD-ROM Поддержка сенсорного экрана для Ubuntu в VirtualBox? как включить и отключить модули php7 в Linux-сервере 16.4 Как определить путь к двоичному процессу процесса? Juju застрял в состоянии «ожидающего рассмотрения» при использовании LXC Сеть перестала работать на Ubuntu 16.04 Почему команда find взорвалась в / run /? Как удалить / удалить файлы резервных копий как сделать перезагрузку wget, если скорость будет ниже определенного порога?

Разница в двух типах команд, использующих grep

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

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

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

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

Нам интересна часть grep .

Синтаксис grep :

 grep [OPTIONS] PATTERN [FILE...] 

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

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

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

Как правильно передать аргумент «PATTERN»?

Параметр pattern должен быть единственным аргументом. Это означает, что вы не можете просто передать несколько слов или что-либо, содержащее пробелы или специальные символы оболочки, потому что пробелы рассматриваются как разделители аргументов в 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\ 

Или, если вы хотите /home/you/path with spaces/textfile строку «Мне нравится 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" 

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

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

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

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


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

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

или используйте -w ( --word-regexp )

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

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

 grep '[[:space:]]install[[:space:]]' /var/log/dpkg.log 

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

 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 . Например, « install ed».


Прецедент:
содержимое тестового файла:

 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