1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
|
```sh
# Найти точное соответствие
Для того чтобы искать соответствия только целым словам, используйте флаг "-w":
ls
'test script.sh' test test_1 test_2
ls | grep -w test
test script.sh
test
# Аналогичного результата можно добиться через регулярное выражение:
ls | grep "\<test\>"
test script.sh
test
# "\<" — начало слова.
# "test" — искомый текст.
# "\>" — конец слова.
# Угловые скобки должны экранироваться, иначе они будут интерпретироваться как простые символы.
# Игнорировать регистр
# По умолчанию, grep чувствительна к регистру, что немного мешает поиску. Проблема решается путем добавления ключа "-i" к команде:
ls | grep -i new
newFile
NewFile
#Вывод файлов с совпадениями. Используйте параметр "-l", чтобы вывести не сами строки, а только пути к файлам, в которых они содержатся:
grep -r -l "libnma" /usr/share
/usr/share/doc/libnma-gtk4-0/copyright
# Параметр "-r" отвечает за рекурсивный поиск - grep прошерстит не только 1 уровень каталога, а пойдет вглубь.
# Поиск по нескольким параметрам. Для того, чтобы передать команде несколько вводных данных для определения совпадений, используется флаг "-e" перед каждым объектом поиска:
ls | grep -i -e new -e old
NewFile
newFile
oldFile
# Эту команду система понимает, как "или-или" и выводит все вхождения указанных слов.
# Использование регулярных выражений.
# Настоящая сила grep проявляется, когда вы переходите от сопоставления простых строк к сопоставлению шаблонов - регулярных выражений.
# Выражения бывают 2 типов: basic и extended. Одна из особенностей второго типа заключается в том, что некоторые символы требуют экранирования для сохранности фич: ?, +, {, |, (, ), <, >.
# Но можно обойтись просто добавлением флага "-E":
ls | grep -E "script|test"
# Квадратные скобки "[]" используются, чтобы провести проверку на соответствие одному из указанных символов:
ls | grep "test[23]"
test2
test3
# Можем указать "-" для того, чтобы использовать диапазон значений:
ls | grep "test[1-3]"
test2
test3
# Каретка "^" используется для поиска строк, которые начинаются с указанного шаблона. Давайте найдем совпадение всех строк, начинающихся с заглавной буквы:
grep "^[A-Z]" myfile
A lot of text
Hello world
# Знак доллара "$" означает конец строки. В результат входят только те элементы, конец которых подходит под шаблон:
grep "world$" myfile
Hello world
hello world
# Точка "." обозначает любой одиночный символ, кроме новой строки. Регулярное выражение "....." обозначает любую строку, содержащую минимум 5 символов:
grep '.....' myfile
# Вертикальная черта "|" выполняет роль логического оператора "ИЛИ":
ls | grep "script\|test"
script
test
# В общем, регулярные выражения прекрасны и многообразны. Детальнее ознакомиться с ними можете по ссылке.
# Экранирование
# Иногда выражения приводят к неожиданным результатам.
# Предположим, вы хотите найти в файле "myfile" только те строки, которые заканчиваются на ".sh".
# Следующая команда выдаст неверный результат, поскольку точка — это регулярное выражение, означающее «любой символ»:
grep ".sh" myfile
script_name.sh
script_namesh
# Чтобы обойти эту проблему, требуется экранировать спецсимвол:
grep "\.sh" myfile
script_name.sh
# Такое решение иногда становится громоздким. К счастью, можно заставить grep забыть о регулярных выражениях и искать буквально то, что мы указываем.
# Для этого используется параметр (fixed) "-F":
grep -F ".sh" myfile
script_name.sh
```
**Полезные опции для поиска файлов через grep**
Иногда нужно найти один/несколько файлов, содержащих определённую строку в: логах, конфигах или исходном коде. Для этого очень часто под рукой оказывается утилита **grep**. Для сводки, интересные флаги и регулярные выражения для grep мы рассматривали тута.
По умолчанию команда фильтрует один файл. Для того чтобы выполнять поиск по каталогу, нужно добавить флаг "**-r**":
```sh
grep -r "root" /etc/
/etc/mdadm/mdadm.conf:MAILADDR root
```
Если хотим подсветить вхождения цветом, используем опцию "**--color=always**":
```sh
grep --color=always -r "root" /etc/
```
Опции "-**C, -B, -A**" вообще имбовые, использую их целую неделю) Вы можете включить отображение не только текущей строки, в которой было найдено вхождение, но и **n** строк **до/после**:
1) **-C**: выводит n строк до и после вхождения;
```sh
grep -C2 -r --color=always "Hello3" ./
./hello-Hello1
./hello-Hello2
./hello:Hello3
./hello-Hello4
./hello-Hello5
```
1) **-B**: выводит n строк перед вхождением;
```sh
grep -B2 -r --color=always "Hello3" ./
./hello-Hello1
./hello-Hello2
./hello:Hello3
```
1) **-A**: выводит n строк после вхождения;
```sh
grep -A2 -r --color=always "Hello3" ./
./hello:Hello3
./hello-Hello4
./hello-Hello5
```
Если наш шаблон поиска походит на регулярное выражения, нужно использовать флаг "**-F**". Таким образом мы говорим команде искать ровно то, что мы запросили - без скрытых подтекстов.
Без флага мы получим строки, в которых присутствует хотя бы 1 символ из набора (**H, e, l, o**). С флагом получим строки с буквальным совпадением:
```sh
grep "[Hello]" hello
Help me please
Helloup
[Hello]
```
```sh
grep -F "[Hello]" hello
[Hello]
```
====================================================
Команды `grep`, `egrep`и `fgrep`являются мощными утилитами для текстового поиска в Linux. Они позволяют пользователям выполнять поиск в файлах или выводе по шаблонам текста с использованием регулярных выражений (regex). В статье мы углубимся в эти команды, их расширенное использование и то, чем они отличаются.
**grep** расшифровывается как **Global Regular Expression Print** . Утилита ищет шаблоны в файлах или входных данных и печатает строки, соответствующие шаблону.
### Начнем с простого: базовый синтаксис и флаги grep:
`grep [OPTIONS] PATTERN [FILE...]
### Популярные опции:
- `-i`: Поиск без учета регистра.
- `-v`: Обратное соответствие (показать строки, не соответствующие шаблону).
- `-r`: Рекурсивный поиск файлов в каталогах.
- `-l`: Показывать только те имена файлов, которые содержат совпадения.
- `-c`: Показать количество совпадающих строк.
- `-n`: Показывать номера строк с соответствующими строками.
- `--color`: Выделение соответствующих шаблонов в выходных данных.
- `-f`опция считывает шаблоны из указанного файла
- `-F`пропускает механизм регулярных выражений, это быстрее, чем использование обычного`grep`
**Примеры:**
Поиск без учета регистра: поиск "error" в файле, игнорируя регистр
`grep -i "error" /var/log/syslog
Рекурсивный поиск в каталоге: поиск шаблона "disk" во всех файлах в /etc/, включая подкаталоги:
`grep -r "disk" /etc/
Отображение номеров строк: отображение строк, содержащих "bash" в ~/.bashrc, включая номера строк
`grep -n "bash" ~/.bashrc
Обратное совпадение: отображение всех строк, не содержащих "root", в /etc/passwd
`grep -v "root" /etc/passwd
Поиск по нескольким шаблонам с -E: поиск строк, содержащих либо "warn", либо "error"
`grep -E "warn|error" /var/log/syslog
`egrep`: расширенный `grep`с увеличенной мощностью
**egrep** является сокращением от **Extended GREP** . По сути, это то же самое, что и `grep -E`, то есть утилита использует расширенные регулярные выражения, которые поддерживают более продвинутые функции регулярных выражений, такие как `+`, `?`, `|`, и скобки без необходимости их экранирования.
Найти строки, содержащие "error" или "fail" без экранирования |
`egrep "error|fail" /var/log/syslog
Эквивалентно:
`grep -E "error|fail" /var/ log /syslog
Найти строки с "color" или "colour"
`egrep "colou?r" file.txt
Расширенные регулярные выражения — шаблоны соответствия: найти строки, где появляется "log", за которым следует 1 или более цифр
`egrep "log[0-9]+" logfiles.txt
Расширенные шаблоны grep: находим то, что другие не могут найти:
1. Мониторинг системных журналов в режиме реального времени
Вы можете использовать `grep` совместно с`tail`для динамического мониторинга журналов и фильтрации определенных шаблонов:
`tail -f /var/log/syslog | grep --color=auto -E "error|warn|critical"
- **Пояснение:** в примере выше выполняется отслеживание `/var/log/syslog`в реальном времени и фильтрует строки, содержащие «error», «warn» или «critical». Опция `--color`выделяет совпадения.
2. Поиск и замена шаблонов в нескольких файлах
Используйте `grep`совместно с `sed`для замены шаблонов в файлах. Это полезно для массовых обновлений в нескольких файлах конфигурации.
`grep -rl "old-string" /path/to/directory | xargs sed -i 's/old-string/new-string/g'
- **Пояснение**: в примере выше выполняется рекурсивный поиск ( `-r`) всех файлов, содержащих «old-string», и передача их для `sed`замены на «new-string» ( `-i`для редактирования файлов на месте).
3. Извлечение определенных данных из больших логов
Для извлечения определенных типов информации, например IP-адресов или временных меток из файла лога, можно использовать расширенные регулярные выражения.
**Пример:** извлечение всех IP-адресов из файла лога:
`grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}" /var/log/apache2/access.log
- **Пояснение**: в примере выше используется `-oE`для сопоставления IP-адресов (формат адреса IPv4, соответствующий регулярному выражению) и их вывода.
**Пример:** извлечение всех временных меток из файлов журнала:
`grep -oE "\[([0-9]{2}/[A-Za-z]+/[0-9]{4}):([0-9]{2}:[0-9]{2}:[0-9]{2})" /var/log/apache2/access.log
- **Пояснение** : в примере выше извлекаются временные метки лога Apache в формате `[dd/Mon/yyyy:hh:mm:ss]`.
4. Аудит прав доступа к файлам
Если вам нужно выполнить аудит безопасности, вы можете использовать `grep`для поиска файлов с определенными разрешениями.
**Пример:** найти все файлы с разрешением `777` в каталоге и его подкаталогах:
`find / -type f -perm 777 2>/dev/null | grep --color=auto "^"
- **Пояснение** в примере выше утилита`find`ищет файлы с разрешениями `777`и направляет вывод в `grep`для их дополнительного выделения цветом.
5. Поиск файлов на основе метаданных (размер, время, владелец)
`grep`может использоваться в сочетании с `find`для поиска файлов на основе более конкретных метаданных, таких как время изменения файла, размер и владельцы.
**Пример:** найти и отобразить файлы размером более 100 МБ со словом «ERROR»:
`find /var/log/ - type f -size +100M - exec grep -H "ERROR" {} \;
- **Пояснение**: этот метод использует `find`для поиска файлов размером более 100 МБ в `/var/log/`,а `-exec`запускает `grep`для поиска строк, содержащих «ERROR».
**Пример:** найти файлы, измененные за последние 7 дней, и выполнить поиск по слову «failure»:
`find /etc/ -type f -mtime -7 -exec grep -H "failure" {} \;
- **Пояснение**: `find`ищет файлы, измененные за последние 7 дней, и передает их `grep`для поиска «failure».
6. Параллельный grep для повышения производительности
При поиске в больших каталогах с большим количеством файлов параллельный запуск `grep` может значительно повысить производительность.
**Пример:** параллельный поиск строки «timeout» в большом каталоге:
`find /path/to/dir -type f | xargs -P 4 grep "timeout"
- **Пояснение**: `xargs -P 4`запускает параллельно 4 процесса `grep`, ускоряя поиск.
7. Поиск множественных сложных шаблонов
Вы можете использовать `grep`для поиска несколько сложных шаблонов, используя расширенные регулярные выражения.
**Пример:** поиск строк, содержащих «error» с последующим числом или любую строку с «timeout»:
`grep -E "error[[:digit:]]+|timeout" /var/log/syslog
- **Пояснение**: этот подход позволяет найти строки, в которых после слова «error» следует одна или несколько цифр, или строки, содержащие слово «timeout».
**Пример:** найти в логах строки, содержащие либо «failed login», либо «successful login»:
`grep -E "(failed|successful) login" /var/log/auth.log
- **Пояснение**: здесь используется расширенное регулярное выражение для сопоставления «failed login» или «successful login».
8. Поиск в двоичных файлах и игнорирование непечатаемых символов
`grep`может использоваться для поиска строк в двоичных файлах, игнорируя непечатаемые символы.
**Пример:** поиск строки «password» во всех двоичных файлах:
`grep -a "password" /usr/bin/*
- **Пояснение**: опция `-a` обрабатывает двоичные файлы как текстовые файлы, позволяя искать понятные человеку строки внутри двоичных файлов.
9. Фильтрация и подсчет уникальных вхождений
Вы можете использовать `grep` совместно с утилитами`sort`и `uniq`для фильтрации и подсчета уникальных шаблонов, таких как IP-адреса, имена пользователей или ошибки.
**Пример:** подсчет уникальных IP-адресов, обращающихся к веб-серверу:
`grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}" /var/log/apache2/access.log | sort | uniq -c | sort -nr
- **Пояснение**: эта команда извлекает IP-адреса из access-лога, сортирует их, подсчитывает уникальные вхождения, а затем сортирует их по частоте.
**Пример:** найти наиболее частые типы ошибок в файле лога:
`grep "ERROR" /var/log/syslog | awk '{print $5}' | sort | uniq -c | sort -nr
- **Пояснение**: команда выше извлекает типы ошибок (предполагая, что 5-е поле — это тип ошибки), подсчитывает уникальные ошибки и сортирует их по частоте.
### Повышение производительности: ускорьте поиск с помощью оптимизации grep
10. Объедините grep с другими инструментами автоматизации
**Пример:** отправка оповещения, если в журналах появляется определенная ошибка
Вы можете создать автоматизированную систему оповещений на основе определенных шаблонов в логах, используя `grep`.
`grep -i "critical error" /var/log/syslog | mail -s "Critical Error Found" admin@example.com
- **Пояснение**: здесь выполняется поиск «critical error» в системном логе и, если она найдена, администратору отправляется электронное письмо с соответствующими строками.
11. Извлечение определенных данных из диапазона строк
Используя `grep`в сочетании с `sed`или `awk`, вы можете извлечь определенные данные из диапазона строк.
**Пример:** извлечение линий между двумя шаблонами:
`sed -n '/START_PATTERN/,/END_PATTERN/p' file.txt | grep "important_string"
- **Пояснение** : в примере выше извлекаются строки между `START_PATTERN`и `END_PATTERN`и передаются в`grep`для поиска `important_string`.
12. grep с удаленных серверов с использованием SSH
Вы можете удаленно выполнять поиск в журналах или файлах на другом сервере, используя SSH и `grep`.
**Пример:** Поиск «error» в удаленных журналах:
`ssh user@remote_server 'grep "error" /var/log/syslog'
- **Пояснение**: в примере выше выполняется команда `grep` на удаленном сервере через SSH.
13. Найти выполненные команды в истории Bash
Чтобы отследить конкретную команду, использовавшуюся пользователями в прошлом, вы можете выполнить поиск в файлах истории bash.
**Пример:** поиск всех выполненных команд `mount` в истории всех пользователей:
`grep "mount" /home/*/.bash_history
- **Пояснение**: команда выше проверяет файлы истории bash всех пользователей на предмет выполнения ими команды `mount`.
14. Расширенное сопоставление с образцом с отрицательным просмотром
`grep`не поддерживает просмотр вперед напрямую, но вы можете добиться похожего поведения с помощью креативного регулярного выражения.
**Пример:** сопоставьте строки, содержащие «error», но не содержащие «network error»:
`grep -E "error" file.txt | grep -v "network error"
- **Пояснение** : сначала команда находит все строки, содержащие «error», а затем исключают строки, содержащие «network error».
Эти расширенные варианты использования демонстрируют универсальность `grep`, `egrep`, и `fgrep`при применении в сложных случаях. Независимо от того, анализируете ли вы логи, ищете в больших наборах данных или автоматизируете административные задачи, эти мощные инструменты помогут вам эффективно найти именно то, что вам нужно.
|