====== Фильтрация вывода ======
===== grep =====
grep [опции] шаблон [файл ...]
grep [опции] [-e шаблон | -f файл] [файл ...]
* **grep 'ключевое слово'** - поиск заданного слова/строки.
* **-B (-A)** - кол-во строк до (после) вхождения.
* **-E (-e)** - использование рег выражения (образец)
* **-P [--perl-regexp]** - рег. выражение Perl
* **-o** - вывод только части строки, подходящей под указанный шаблон
* **-с [--count]** - кол-во строк совпадающего (не совпадающего) результата
* **-D (-d)** - действие, применимо к уст-вам или каталогам, можно читать как обычные файлы, в т.ч. рекурсивно
* **-f [--file]** - шаблон из файла, по одному в каждой строке
* **-v [--invert-match]** - изменить смысл совпадения, выбор не совпадающих строк
* **-w [--word-regexp] (-x [--line-regexp])** - совпадение только всего слова (всей строки)
:!: Примеры
# Извлечение IP адреса
echo -e "3.123.32.24\nFirst\n567" | grep -Eo "([0-9]{0,3}\.){3}[0-9]{0,3}"
# Извлечение IP адресов с ошибкой авторизации из auth.log
cat /var/log/auth.log | grep Failed | grep -Eo "([0-9]{1,3}\.){3}[0-9]{1,3}" | sort --unique > ip.list
# Убрать из вывода пустые и закоментированные строки
cat /etc/telegraf/telegraf.conf | grep -Ev "^#|^ #|^$"
# Список IP активных подключений
ss -ntlua | grep "8086" | awk '{print $6}' | grep -Eo "([0-9]{1,3}\.){3}[0-9]{1,3}" | sort --unique
: Скриптом добавить эти адреса в блок
# Сначала создаем отдельную цепочку для этого и ставим ее в начало "входа" INPUT
iptables -N BLACKLIST
iptables -I INPUT -j BLACKLIST
# Затем читаем из файла список адресов и добавляем правила
readarray lst < /../ip.list
for i in "${lst[@]}"
do
/sbin/iptables -A BLACKLIST -s $i -j DROP
done
===== awk =====
Общий синтаксис: **"pattern {action}"**, действием могут быть: **exit**, **next**, **print**, **printf**.\\
Регулярные выражения обрамляются слэшами **"/regex pattern/ {action}"**.\\
* **$№** - указывает номер поля для вывода, разделяются пробелами.
* $0 - вся строка
* $NF - последнее поле с его номером
* **-OFS** - задать разделитель в выводе
* **BEGIN/END** - имеют собственный набор д-й, выполняются один раз
* **-F** - указать разделитель во входных данных, вместо пробела
* **substr (s, a, b)** - подстрока строка-s, кол-во- b, начать с- a. Используется внутри 'print'
*
* **Встроенные переменные:**
* **NF** - Количество полей в записи
* **NR** - Номер текущей записи
* **FILENAME** - Имя входного файла, который в данный момент обрабатывается
* **FS** - Разделитель полей
* **RS** - Разделитель записей
* **OFS** - Разделитель выходных полей
* **ORS** - Разделитель выходной записи
:!: Поиск и замена
Преимущество перед sed в том что сразу экранируются некоторые символы, но к сожалению не все\\
Пропустил / а вот & b \ тоже не пропустил
# Просто замена, PRINT для вывода результата на консоль
awk '{gsub(//,"this_is_uname"); print }' file
# Сохранить резы в тот же файл, чтобы сразу нет такого параметра
awk '{gsub(//,"this_is_uname"); print }' file > tmp && mv tmp file
# Тоже самое только групповая замена
awk '{\
gsub(//,"this_is_uname"); \
gsub(//,"this_is_passwd"); \
gsub(//,"https://my-site"); \
print }' file > tmp && mv tmp file
# Сохранить изменения в этом же файле !! Это уже другая утилита
gawk -i inplace '{ gsub(//, "https://my-site") }; { print }' file
:!: Примеры
cat 'text' | awk {'print $1,$3'}
# Задать разделитель
cat 'text' | awk 'OFS="-" {print $1,$3}'
# Вывод имени файла и кол-во строк
awk 'END { print "File", FILENAME, "contains", NR, "lines." }' teams.txt
awk 'length $0 > 2' letters.txt
awk 'BEGIN { print "HI" } { print $0 } END { print "BYE!" }' letters.txt
awk 'BEGIN { printf "%-10s %s\n", "Col1", "Col2"; \
printf "%-10s %s\n", "----", "------" } \
{ printf "%-10s %s\n", $1, $2 }' mail-data
awk '/[aeiou]{5}/' /usr/share/dict/words
Группировка и сложение
US|A|1000|2000
US|B|1000|2000
US|C|1000|2000
UK|1|1000|2000
UK|1|1000|2000
UK|1|1000|2000
awk 'BEGIN { FS=OFS=SUBSEP="|"}{arr[$1,$2]+=$3+$4 }END {for (i in arr) print i,arr[i]}' myfile
US|A|3000
US|B|3000
US|C|3000
UK|1|9000
# Вариации
# Сложить кол-во указанное напротив значений
awk 'BEGIN { FS=OFS} {arr[$1]+=$2 }END {for (i in arr) print i,arr[i]}' myfile | sort -rnk2
# Два столбца
awk 'BEGIN { FS=OFS} {arr[$1]+=$2; arr2[$1]+=$3 }END {for (i in arr) print i,arr[i],arr2[i]}' myfile | sort -rnk2
===== sed =====
Потоковый редактор текста. Можно использовать для поиска, вставки, замены и удаления фрагментов в файле или потоке вывода.\\
sed опции -e команды файл
Опции:
* **-n** - не выводить содержимое буфера шаблона в конце каждой итерации
* **-f** - прочитать команды редактирования из файла
* **-i** - сделать резервную копию файла
* **-r** - поддержка расширенного синтаксиса рег выражений
* **-s** - несколько файлов рассматривать как отдельные потоки, а не один сплошной
У утилиты есть **два буфера**, **активный** и **дополнительный**. Выполняется заданное условие для каждой строки.\\
Очередная строка попадает сначала в активный буфер, выполняются команды, выводится в поток вывода и буфер очищается, в доп буфере хранится предыдущая строка.\\
Каждой команде можно передать адрес строки, к которой ее применить (по умолчанию для всех):
* **номер** - номер строки
* **первая ~шаг (~число)** - с первой, далее с указанным шагом (номер строки кратный указанному числу)
* **$** - последняя строка
* **/рег. выражение/** - подходящая под рег выражение
* **номер, номер** - с номера до номера
* **номер, /рег. выражение/** - с номера до рег выражения
* **номер, +кол-во** - с номера до кол-ва
Некоторые команды:
* **q** - завершает работу сценария
* **d** - удаляет буфер и запускает следующую итерацию
* **p (n)** - вывод содержимого буфера шаблона (причитать в него след строку)
* **s/что_заменять/на_что_заменять/опции** - замена символов, поддержка рег выражений
* **y/символы/символы** - замена символов
* **w** - записать содержимое буфера в шаблона в файл
* **i** - сохранять изменения в файл
Можно передавать несколько команд, для этого нужно разделить их точкой с запятой или две опции -e.\\
:!: Поиск и замена
:!: **Не прпускает символ амперсанд и оба слеша**\\
# -i чтобы сохранить в тот же файл
sed -i 's//this_uname/g' file
:!: Примеры
# Вывод с пятой по десятую строки
$ sed -n '5,10p' /file
# Весь файл кроме строк с 1 по 20
$ sed '1,20d' /file
# Замена во всех строках
$ sed 's/root/loost/g' /file
# Замена только в указанных строках
$ sed '1,10 s/0/10/g' /file
# Удаление последних символов
$ sed -e "s/.$//" /file
Удалить все пробелы
$ echo "string" | sed -r 's/\s+//g'
===== RegEx =====
Относится как к **grep** так и к **awk**.\\
* **\** - экранирование
* **^($)** - начало (конец) строки
* **.** - любой одиночный символ
* **[]** - перечень/диапазон символов, можно несколько диапазонов, что бы исключить символ поставьте перед ним \
* например: [A-Za-z0-9\F]
* ***** - любое кол-во вхождения пред выражения
* **?** - одно либо не одного вхождения пред выражения
* **+** - как минимум одно вхождение пред выражения
* **{n} {n,} {,m} {n,m}** - повторы вхождения пред выражения
* **|** - оператор ИЛИ
===== RegEx (Perl) =====
Синтаксис в целом соответствует
* **^ ($)** - Начало (конец) строки
* **. (*)** - любой одиночный символ (ноль или более вхождений пред выражения)
* **[...] ([^...])** - любой одиночный символ в скобках (не указанный в скобках)
* **+ (?)** - 1 одно или несколько вхождений (0 или 1 вхождение)
* **{n}, {n,}, {n,m}** - ровно n, n или несколько вхождений, ровно от n до m
* **a | b** - "либо"
* **i** - не учитывать регистр
* **\K** - задает условное начало строки от найденного фрагмента
===== Примеры. Разное =====
:!: Пример: over
Источник для фильтрации
10.1.192.62 - - [18/Aug/2020:01:08:50 +0000] "POST /zabbix/jsrpc.php?sid=/b59ea3cc3hryh446/&type=9&method=screen.get×tamp=1597712895283&mode=0&screenid=58&groupid=&hostid=10262&pageFile=screens.php&profileIdx=web.screens.filter&profileIdx2=58&screenitemid=9594&from=2020-08-14%2000%3A00%3A00&to=2020-08-14%2006%3A00%3A00 HTTP/1.1" 200 845 "Chrome/84.0.4147.125 Safari/537.36"
10.1.192.38 - - [18/Aug/2020:01:08:50 +0000] "POST /zabbix/jsrpc.php?sid=/m85486u/k7kkjklij/&type=9&method=screen.get×tamp=1597712895291&mode=0&screenid=58&groupid=&hostid=10262&pageFile=screens.php&profileIdx=web.screens.filter&profileIdx2=58&screenitemid=9595&from=2020-08-14%2000%3A00%3A00&to=2020-08-14%2006%3A00%3A00 HTTP/1.1" 200 848 "Chrome/84.0.4147.125 Safari/537.36"
10.1.192.38 - - [18/Aug/2020:01:08:50 +0000] "POST /zabbix/jsrpc.php?sid=/kjtg986u76klju89/&type=9&method=screen.get×tamp=1597712895338&mode=0&screenid=58&groupid=&hostid=10262&pageFile=screens.php&profileIdx=web.screens.filter&profileIdx2=58&screenitemid=9597&from=2020-08-14%2000%3A00%3A00&to=2020-08-14%2006%3A00%3A00 HTTP/1.1" 200 840 "Chrome/84.0.4147.125 Safari/537.36"
10.1.192.38 - - [18/Aug/2020:01:08:50 +0000] "POST /zabbix/jsrpc.php?sid=/90ghdkyj78jyyfui/&type=9&method=screen.get×tamp=1597712895349&mode=0&screenid=58&groupid=&hostid=10262&pageFile=screens.php&profileIdx=web.screens.filter&profileIdx2=58&screenitemid=9598&from=2020-08-14%2000%3A00%3A00&to=2020-08-14%2006%3A00%3A00 HTTP/1.1" 200 828 "Chrome/84.0.4147.125 Safari/537.36"
10.1.192.67 - - [18/Aug/2020:01:08:50 +0000] "POST /zabbix/jsrpc.php?sid=/htrifh6gb476fdhr/&type=9&method=screen.get×tamp=1597712895355&mode=0&screenid=58&groupid=&hostid=10262&pageFile=screens.php&profileIdx=web.screens.filter&profileIdx2=58&screenitemid=9599&from=2020-08-14%2000%3A00%3A00&to=2020-08-14%2006%3A00%3A00 HTTP/1.1" 200 873 "Chrome/84.0.4147.125 Safari/537.36"
# 1. Фильтруем строки c нужным IP
# 2. Из этих строк вырезаем значение между "sid=/" и "&"
# 3. Обрезаем последний символ, им будет слеш
# 4. Сортируем
cat log.txt | grep 10.1.192.38 | grep -Po 'sid=/\K[^&]*' | sed -e "s/.$//" | sort
:!: OverAll
# Вывод только имени пользователя, из записей в логе, в уникальном списке
sudo cat /var/log/auth.log.1 | grep -oP 'USER=\K[^;]*' | sort -u
# Список подключений из ss
sudo ss -ntlua | grep "8086" | awk '{print $6}' | grep -Eo "([0-9]{1,3}\.){3}[0-9]{1,3}" | sort --unique
Вывод файла, сортировка, подсчет вхождения, вывод таблицей
cat list.csv | sort | uniq -c | [column -t |] sort -r
====== Просмотр файлов ======
* **cat** - содержимое файла в поток вывода
* **tail** - заданное кол-во строк с конца файла + интерактивное обновление
* **head** - заданное кол-во строк с начала файла
* **less** - постраничный просмотр
* **column** - вывод в табличном виде
**cat**
Для записи в файл можно использовать перенаправление ввода **>>**.
* **-n (-b)** - нумеровать строки (только не пустые).
* **-s** - удалять пустые строки.
* **-E** - показывать символ $ в конце каждой строки.
* **-T** - отображать символ табуляции.
**tail**
* **-f [--pid]** - авто-обновление [закрыться с процессом].
* **-s сек** - частота обновления.
* **-n** - кол-во строк (10 по умолчанию).
**head**
* **-n** - кол-во строк (10 по умолчанию).
* **--lines=[-]NUM** - весь текст, кроме последних NUM строк.
* **-z** - символ новой строки.
**less**
* **-i (-I)** - игнорировать регистр паттерна
* **-n (-N)** - не выводить (выводить) номера строк
**column**
Можно перенаправлять вывод, можно подавать файлы. Гуглятся целый ряд всяких параметров но что то нихрена толком не работает
* **-t** - для табличной формы
* **-s "symb"** - символ для разделения
**uniq**
https://losst.pro/komanda-uniq-linux\\