Привет всем! Сегодня изучим команду
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 (к сожалению, английский язык).
Всем пока и удачи в обучении!