пятница, 27 сентября 2013 г.

Команда grep. Регулярные выражения.

Привет всем! Сегодня изучим команду grep, а также регулярные выражения.

Команда grep позволяет вывести все строки данного на вход файла, которые содержат некоторое слово:

grep слово имя_файла

Чтобы перейти к использованию этой команды, давайте сначала создадим файл мой_файл со следующим содержимым:


Это первая строка.
Вторая строка.
Это третья строка.
А это четвёртая.
Здесь будет несколько чисел: 100 2 35 4 38
Здесь ещё несколько: 2 3 5 21 13.
Лаллалаалааалала
А тут только одно: 123.
12345


Теперь введём в терминал:

grep строка мой_файл

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

Это первая строка.
Вторая строка.
Это третья строка.

То есть только те строки, где присутствует слово строка.
Поэкспериментируйте:

grep "2 3" мой_файл
grep 5 мой_файл
grep Здесь мой_файл
grep Это мой_файл 
grep это мой_файл
grep привет мой_файл

Как вы уже, возможно, догадались, второй аргумент может содержать пробельные символы. То есть, правильнее будет говорить, что это не слово, а подстрока (нечто лежащее внутри строки).

Скажу более, второй аргумент - это регулярное выражение! Регулярные выражения напоминают шаблоны, они тоже задают одним выражением целый набор строк.

Давайте поэтапно разберём конструкции регулярных выражений.

Символ . соответствует ровно одному любому символу. Это то же самое, что и ? в шаблонах. Попробуем:

grep ".то" мой_файл  (Если это регулярное выражение, то оно должно быть в кавычках!)

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

[] задают набор символов, аналогично как и в шаблонах:


grep "[Ээ]то" мой_файл

Если в скобках поставить ^, то это будет означать: "любой символ, кроме заданного набора". Это то же, что и ! в шаблонах:

grep "[^Ээ]то" мой_файл

А вот, что касается символа *, то он имеет совершенной иной смысл. Сама по себе звёздочка не означает какого либо символа. Она читается примерно так: "ноль или более повторений предыдущего символа". Приведу примеры:

ab*c   соответствует таким строкам: ac, abc, abbc, abbbc, abbbbc и так далее.
a[bc]*d   соответствует, например, таким: ad, abd, acd, abbd, accd, abcd, acbd, acbcd. Можно прочесть как: "Сначала a, затем любое количество символов b и c. В конце символ d"
.*   Можно прочесть как: "Любое количество любых символов". То есть, это соответствует любой строке, в том числе и пустой.

Давайте попробуем использовать звёздочку:

grep "[ал]*" мой_файл

^ и $ означают начало и конец строки, соответственно. Например, чтобы вывести все строки, начинающиеся только на З, можно воспользоваться следующей командой:

grep "^З" мой_файл

Строчки, заканчивающиеся точкой, можно получить так:

grep "\.$" мой_файл   (Если мы имеем ввиду именно точку, а не любой символ, то мы должны писать \. , точно так же, как и в шаблонах)

Есть ещё пара символов.
+ - то же самое, что и звёздочка, только означает "один или более", вместо "ноль или более".
? похож на звёздочку, только читается как "один или ноль предыдущих символов", вместо "один или более предыдущих символов".

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

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

grep "^[^0-9].*[0-9 ]\+.\?$" мой_файл   (примечание: диапазон задаётся так же, как и в шаблонах: знаком минус)

Разберём, что же здесь происходит.

^ - говорит нам о начале строки. Затем стоит ровно один символ, который не является цифрой: [^0-9]. Далее, ноль или более любых символов (.*). Потом, цифры и пробелы, которые встречаются один или более раз ([0-9 ]\+). Это соответствует числам,  записанным через пробелы. В конце строки у нас, возможно, есть точка (.\?$).

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

Если появилось желание углубиться в данную тему, советую почитать дополнительную информацию в интернете, а также в мануале: man regex (к сожалению, английский язык).

Всем пока и удачи в обучении!


Комментариев нет:

Отправить комментарий