Awk bash: язык обработки данных awk / Блог компании RUVDS.com / Хабр
Использование awk в Linux
Текст это сердце Unix. Философия «все есть файл» полностью пронизывает всю систему и разработанные для нее инструменты. Вот почему работа с текстом является одним из обязательных навыков не только системного администратора, но и обычного пользователя Linux, который хочет поглубже разобраться в этой операционной системе.
Команда awk — один из самых мощных инструментов для обработки и фильтрации текста, доступный даже для людей никак не связных с программированием. Это не просто утилита, а целый язык разработанный для обработки и извлечения данных. В этой статье мы разберемся как пользоваться awk.
Синтаксис команды awk
Сначала надо понять как работает утилита. Она читает документ по одной строке за раз, выполняет указанные вами действия и выводит результат на стандартный вывод. Одна из самых частых задач, для которых используется awk — это выборка одной из колонок. Все параметры awk находятся в кавычках, а действие, которое надо выполнить — в фигурных скобках. Вот основной её синтаксис:
$ awk опции ‘условие {действие}’
$ awk опции ‘условие {действие} условие {действие}’
С помощью действия можно выполнять преобразования с обрабатываемой строкой. Об этом мы поговорим позже, а сейчас давайте рассмотрим опции утилиты:
- -F, —field-separator — разделитель полей, используется для разбиения текста на колонки;
- -f, —file — прочитать данные не из стандартного вывода, а из файла;
- -v, —assign — присвоить значение переменной, например foo=bar;
- -b, —characters-as-bytes — считать все символы однобайтовыми;
- -d, —dump-variables — вывести значения всех переменных awk по умолчанию;
- -D, —debug — режим отладки, позволяет вводить команды интерактивно с клавиатуры;
- -e, —source — выполнить указанный код на языке awk;
- -o, —pretty-print — вывести результат работы программы в файл;
- -V, —version — вывести версию утилиты.
Это далеко не все опции awk, однако их вам будет достаточно на первое время. Теперь перечислим несколько функций-действий, которые вы можете использовать:
- print(строка) — вывод чего либо в стандартный поток вывода;
- printf(строка) — форматированный вывод в стандартный поток вывода;
- system(команда) — выполняет команду в системе;
- length(строка) — возвращает длину строки;
- substr(строка, старт, количество) — обрезает строку и возвращает результат;
- tolower(строка) — переводит строку в нижний регистр;
- toupper(строка) — переводить строку в верхний регистр.
Функций намного больше, но чтобы не загромождать статью я привел только те, которые мы будем использовать сегодня, а также ещё несколько для чтобы вы могли оценить масштаб возможностей утилиты.
В функциях-действиях можно использовать различные переменные и операторы, вот несколько из них:
- FNR — номер обрабатываемой строки в файле;
- FS — разделитель полей;
- NF — количество колонок в данной строке;
- NR — общее количество строк в обрабатываемом тексте;
- RS — разделитель строк, по умолчанию символ новой строки;
- $ — ссылка на колонку по номеру.
Кроме этих переменных, есть и другие, а также можно объявлять свои.
Условие позволяет обрабатывать только те строки, в которых содержатся нужные нам данные, его можно использовать в качестве фильтра, как grep. А ещё условие позволяет выполнять определенные блоки кода awk для начала и конца файла, для этого вместо регулярного выражения используйте директивы BEGIN (начало) и END (конец). Там ещё есть очень много всего, но на сегодня пожалуй достаточно. Теперь давайте перейдем к примерам.
Использование awk в Linux
Простейшая и часто востребованная задача — выборка полей из стандартного вывода. Вы не найдете более подходящего инструмента для решения этой задачи, чем awk. По умолчанию awk разделяет поля пробелами. Если вы хотите напечатать первое поле, вам нужно просто использовать функцию print и передать ей параметр $1, если функция одна, то скобки можно опустить:
echo 'one two three four' | awk '{print $1}'
Да, использование фигурных скобок немного непривычно, но это только в первое время. Вы уже догадались как напечатать второе, третье, четвертое, или другие поля? Правильно это $2, $3, $4 соответственно.
echo 'one two three four' | awk '{print $3}'
Иногда необходимо представить данные в определенном формате, например, выбрать несколько слов. AWK легко справляется с группировкой нескольких полей и даже позволяет включать статические данные:
echo 'one two three four' | awk '{print $3,$1}'
echo 'one two three four' | awk '{print "foo:",$3,"| bar:",$1}'
Если поля разделены не пробелами, а другим разделителем, просто укажите в параметре -F нужный разделитель в кавычках, например «:» :
echo 'one mississippi:two mississippi:three mississippi:four mississippi' | awk -F":" '{print $4}'
Но разделитель не обязательно заключать в кавычки. Следующий вывод аналогичен предыдущему:
echo 'one mississippi:two mississippi:three mississippi:four mississippi' | awk -F: '{print $4}'
Иногда нужно обработать данные с неизвестным количеством полей. Если вам нужно выбрать последнее поле можно воспользоваться переменной $NF. Вот так вы можете вывести последнее поле:
echo 'one two three four' | awk '{print $NF}'
Также вы можете использовать переменную $NF для получения предпоследнего поля:
echo 'one two three four' | awk '{print $(NF-1)}'
Или поля с середины:
echo 'one two three four' | awk '{print $((NF/2)+1)}'
echo 'one two three four five' | awk '{print $((NF/2)+1)}'
Все это можно сделать с помощью таких утилит как sed, cut и grep но это будет намного сложнее.
Как я рассказывал выше, awk обрабатывает одну строку за раз, вот этому подтверждение:
echo -e 'one 1\n two 2' | awk '{print $1}'
А вот пример фильтрации с помощью условия, выведем только строку, в которой содержится текст one:
echo -e 'one 1\n two 2' | awk '/one/ {print $1}'
А вот пример использования операций с переменными:
echo -e 'one 1\n two 2' | awk '{sum+=$2} END {print sum}'
Это означает что мы должны выполнять следующий блок кода для каждой строки. Это можно использовать, например, для подсчета количества переданных данных по запросам из журнала веб-сервера.
Представьте себе, у нас есть журнал доступа, который выглядит так:
Мы можем подсчитать, что количество переданных байт, это десятое поле. Дальше идёт User-Agent пользователя и он нам не интересен:
cat /var/log/apache2/access.log | awk '{print $10}'
Вот так можно подсчитать количество байт:
< requests.log awk '{totalBytes+=$NF} END {print totalBytes}'
Это только несколько примеров показывающих использование awk в Linux , освоив awk один раз в получите очень мощный и полезный инструмент на всю жизнь.
Использование awk в Linux. — ИТ Проффи
.Основным средством представления данных а также взаимодействия пользователя с системой в Linux является текст или текстовые данные. Как известно, управление операционной системой (ОС) Linux осуществляется, преимущественно, через терминал консоли командной оболочки, локальный или удалённый. Даже в самых современных дистрибутивах Linux, имеющими на борту удобные графические оболочки, всё же без использования командной оболочки не обойтись. Так уж сложилось исторически, поскольку создатели системы UNIX, чьим потомком является Linux, ещё на начальных этапах разработки системы старались всячески облегчить работу в командной оболочке и повысить «производительность труда» при работе с ней — ведь это напрямую связано с обработкой текстовых данных, начиная с ввода команд и редактирования файлов и заканчивая управлением потоками ввода/вывода.
В результате система совершенствовалась и дополнялась специализированными утилитами, которые способны ускорить, причём очень существенно, скорость и эффективность работы с текстовыми данными. Одной из таких утилит является awk — в общем случае текстовый фильтр для сортировки, выборки и даже программирования управления текстовыми данными. Благодаря таким инструментам и некоторым хитростям использования командной оболочки опытный пользователь способен без использования графических пользовательских интерфейсов (GUI) управлять системой и данными заметно быстрее и эффективнее нежели при задействовании всевозможных графических приложений.
Как работает awk?
На самом деле awk – это изначально язык программирования, предназначенный для обработки текста/данных. Поскольку, как уже отмечалось, в Linux-системах основной средой для взаимодействия между пользователем и машиной является текст, то обработка достаточно больших его объёмов вручную способна была парализовать на некоторое время процесс выполнения основной работы. Требовался инструмент для обеспечения автоматической обработки данных и позволяющий использовать эту возможность «на лету», т. е. прямо при работе в командной оболочке. Лучшим средством для достижения этой цели является использование специализированного языка программирования и регулярных выражений, которое реализовано в виде одноимённой утилиты — команды awk.
Справедливо заметить, что awk – это прежде всего Си-подобный язык программирования, но для удобства понимания, под awk принято понимать утилиту или команду. Разработчиками языка AWK являются Alfred V. Aho, Peter J. Weinberger и Brian W. Kernighan, по сокращённым инициалам которых язык и получил своё название. Создан язык в 1977 году. Кстати, на основе AWK когда-то был создан язык Perl, который и по сей день является одним из самых мощных языков для высокопроизводительной обработки данных.
В качестве исходных данных awk принимает на вход строку и после её обработки в зависимости от конкретных опций выдаёт результат. Исходные данные могут поступать из файла или из вывода другой команды/программы. Самым распространённым случаем использования awk является выборка определённых столбцов из результата вывода других команд, например:
$ ll | awk '{print $9}'
В результате вывод будет примерно таким:
Следует напомнить, что по-умолчанию вывод команды ll выглядит следующим образом:
Как видно, команда awk помогла вывести только отдельный столбец из общего вывода ll – с именами каталогов и файлов.
Конечно, для решения подобных задач существует утилита grep, но awk гораздо быстрее и производительнее для обработки больших и сложных массивов данных.
Синтаксис
Для awk существуют понятия команды и действий, выполняемых этой командой. Действия, которые необходимо выполнить, заключаются в фигурные скобки {}, а сама команда (в которую и входят действия) содержится в одинарных кавычках ‘ ‘:
awk '{action1;action2;actionN}'
Несколько действий разделяются (в соответствии с семантикой языка AWK) символом точки с запятой.
Следующая команда выведет весь файл file.txt подобно команде cat
awk '{print}' file.txt
Вывод строки содержащую ‘string’
awk '/'string'/{print}' file.txt
Оператор print принимает выражения $0, $1, $2… Эти выражения указывают какие поля следует выводить, например. Оператор $0 выведет весь файл. Например
awk '{print $0}' file.txt
Аналогично awk ‘{print}’ file.txt выведет весь файл
Если нам нужно получить только первый столбец
awk '{print $1}' file.txt
Второй awk ‘{print $2}’ file.txt и т.д.
Следующие примеры демонстрируют использование awk в самых распространённых ситуациях:
$ dpkg -l | awk '{print $2}'
В результате будет выведен список с именами установленных пакетов. Если же нужно узнать, к примеру, какие пакеты PHP или Apache установлены в системе. Следует дать команду:
$ dpkg -l | awk '/'php'/{print $2}'
или для Apache:
$ dpkg -l | awk '/'apache'/{print $2}'
Выражение для поиска/сортировки/отбора заключается, как можно видеть, между символами /’ ‘/.
Примеры использования awk
Для лучшего понимания стоит рассмотреть некоторые примеры использования утилиты awk. Для вывода/печати конкретных (например, второго и четвёртого) столбцов:
awk '{print $1,$3}'
Вывести все столбцы:
awk '{print $0}'
Вывод элементов третьего столбца, в наименовании которых содержится паттерн /’pattern’/:
awk ' /'pattern'/ {print $2} '
Напечатать количество строк в файле:
awk 'END { print NR }' targetfile
где NR – Number of Rows, т. е. количество строк. Для задания регулярных выражений:
awk '$1 ~/P/' targetfile
Здесь отбору подлежат все пункты в первом столбце, имена которых начинаются на «P».
awk '$1 ~!/P/' targetfile
Здесь обратное условие, определяемое символом «!», т. е. выбраны будут все пункты из первого столбца и имена которых не начинаются на «P».
Следующая команда выводит количество байтов всех файлов, которые последний раз изменялись в октябре:
ls -l | awk '$6 == "окт." { sum += $5 } END { print sum }'
По умолчанию в качестве разделителя используется пробел или табуляция. Для того что бы задать свой разделитель нужно использовать ключ «-F». Например для получения списка всех пользователей системы выполните команду
awk -F":" '{ print $1 }' /etc/passwd
Если бы мы запустили утилиту без указания разделителя, то вывод был бы таким
Конечно же, в приведённых примерах демонстрируются далеко не все возможности awk. Однако для эффективной работы в командной оболочке Linux, да и вообще с системой вышеприведённых примеров вполне достаточно. Поскольку они показывают общие принципы построения команд и действий для awk. Что позволяет создавать конкретные и более сложные конструкции в зависимости от конкретной задачи. Для более глубокого и масштабного использования утилиты awk. Рекомендуется посвятить некоторое время на изучения самого языка AWK.
Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.
Команда AWK в Unix / Linux с примерами
Awk — это язык сценариев, используемый для манипулирования данными и генерации отчетов. Язык программирования команд awk не требует компиляции и позволяет пользователю использовать переменные, числовые функции, строковые функции и логические операторы.
Awk — это утилита, которая позволяет программисту писать крошечные, но эффективные программы в форме операторов, определяющих текстовые шаблоны, которые нужно искать в каждой строке документа, и действие, которое нужно предпринять, когда совпадение найдено в линия. Awk в основном используется для сканирования и обработки рисунков. Он ищет один или несколько файлов, чтобы увидеть, содержат ли они строки, соответствующие указанным шаблонам, а затем выполняет связанные действия.
Awk сокращен от имен разработчиков — Aho, Weinberger и Kernighan.
Что мы можем сделать с AWK?
1. Операции AWK:
(а) Сканирует файл построчно
(б) Разбивает каждую строку ввода на поля
(c) Сравнивает входную строку / поля с шаблоном
(d) Выполняет действие (я) на согласованных линиях
2. Полезно для:
(а) Преобразование файлов данных
(б) производить отформатированные отчеты
3. Конструкции программирования:
(а) Форматировать выходные строки
(б) Арифметические и строковые операции
(в) условные выражения и циклы
Синтаксис:
awk options 'selection _criteria {action }' input-file > output-file
Параметры:
-f program-file : Reads the AWK program source from the file program-file, instead of from the first command line argument. -F fs : Use fs for the input field separator
Примеры команд
Пример:
Рассмотрим следующий текстовый файл в качестве входного файла для всех случаев ниже.
$cat > employee.txt
ajay manager account 45000 sunil clerk account 25000 varun manager sales 50000 amit manager account 47000 tarun peon sales 15000 deepak clerk sales 23000 sunil peon sales 13000 satvik director purchase 80000
1. Поведение Awk по умолчанию : по умолчанию Awk печатает каждую строку данных из указанного файла.
$ awk '{print}' employee.txt
Выход:
ajay manager account 45000 sunil clerk account 25000 varun manager sales 50000 amit manager account 47000 tarun peon sales 15000 deepak clerk sales 23000 sunil peon sales 13000 satvik director purchase 80000
В приведенном выше примере шаблон не указан. Таким образом, действия применимы ко всем линиям. Действие print без каких-либо аргументов печатает всю строку по умолчанию, поэтому она печатает все строки файла без сбоев.
2. Напечатайте строки, которые соответствуют данному шаблону.
$ awk '/manager/ {print}' employee.txt
Выход:
ajay manager account 45000 varun manager sales 50000 amit manager account 47000
В приведенном выше примере команда awk печатает все строки, которые совпадают с ‘manager’.
3. Разделение строки на поля: для каждой записи, т. Е. Строки , команда awk разбивает запись, разделенную пробелом по умолчанию, и сохраняет ее в переменных $ n. Если в строке 4 слова, она будет сохранена в $ 1, $ 2, $ 3 и $ 4 соответственно. Кроме того, $ 0 представляет всю строку.
$ awk '{print $1,$4}' employee.txt
Выход:
ajay 45000 sunil 25000 varun 50000 amit 47000 tarun 15000 deepak 23000 sunil 13000 satvik 80000
В приведенном выше примере, $ 1 и $ 4 представляют поля Имя и Зарплата соответственно.
Встроенные переменные в Awk
Встроенные переменные Awk включают переменные поля — $ 1, $ 2, $ 3 и т. Д. ($ 0 — вся строка) — которые разбивают строку текста на отдельные слова или фрагменты, называемые полями.
NR: команда NR ведет текущий подсчет количества входных записей. Помните, что записи обычно являются строками. Команда Awk выполняет инструкции шаблона / действия один раз для каждой записи в файле.
NF: команда NF ведет подсчет количества полей в текущей входной записи.
Команда FS: FS содержит символ разделителя полей, который используется для разделения полей в строке ввода. По умолчанию используется «пробел», что означает пробел и символы табуляции. FS можно переназначить другому символу (обычно в BEGIN), чтобы изменить разделитель полей.
Команда RS: RS хранит символ разделителя текущей записи. Поскольку по умолчанию входная строка является входной записью, символом разделения записей по умолчанию является символ новой строки.
Команда OFS: OFS сохраняет разделитель выходных полей, который разделяет поля, когда Awk печатает их. По умолчанию это пустое место. Всякий раз, когда в print есть несколько параметров, разделенных запятыми, он печатает значение OFS между каждым параметром.
Команда ORS: ORS хранит разделитель выходных записей, который разделяет выходные строки, когда Awk печатает их. По умолчанию используется символ новой строки. print автоматически выводит содержимое ORS в конце того, что ему дано для печати.
Примеры:
Использование встроенных переменных NR (Показать номер строки)
$ awk '{print NR,$0}' employee.txt
Выход:
1 ajay manager account 45000 2 sunil clerk account 25000 3 varun manager sales 50000 4 amit manager account 47000 5 tarun peon sales 15000 6 deepak clerk sales 23000 7 sunil peon sales 13000 8 satvik director purchase 80000
В приведенном выше примере команда awk с NR печатает все строки вместе с номером строки.
Использование встроенных переменных NF (Показать последнее поле)
$ awk '{print $1,$NF}' employee.txt
Выход:
ajay 45000 sunil 25000 varun 50000 amit 47000 tarun 15000 deepak 23000 sunil 13000 satvik 80000
В приведенном выше примере $ 1 представляет имя, а $ NF представляет зарплату. Мы можем получить Зарплату, используя $ NF, где $ NF представляет последнее поле.
Другое использование встроенных переменных NR (строка дисплея от 3 до 6)
$ awk 'NR==3, NR==6 {print NR,$0}' employee.txt
Выход:
3 varun manager sales 50000 4 amit manager account 47000 5 tarun peon sales 15000 6 deepak clerk sales 23000
Больше примеров
Для данного текстового файла:
$cat > geeksforgeeks.txt A B C Tarun A12 1 Man B6 2 Praveen M42 3
1) Чтобы напечатать первый элемент вместе с номером строки (NR), отделенным знаком «-» от каждой строки в geeksforgeeks.txt:
$ awk '{print NR "- " $1 }' geeksforgeeks.txt
1 - Tarun 2 – Manav 3 - Praveen
2) Чтобы вернуть вторую строку / элемент из geeksforgeeks.txt:
$ awk '{print $2}' geeksforgeeks.txt
A12 B6 M42
3) Распечатать любую непустую строку, если она есть
$ awk 'NF > 0' geeksforgeeks.txt
0
4) Чтобы найти длину самой длинной строки в файле:
$ awk '{ if (length($0) > max) max = length($0) } END { print max }' geeksforgeeks.txt
13
5) Для подсчета строк в файле:
$ awk 'END { print NR }' geeksforgeeks.txt
3
6) Печать строк длиной более 10 символов:
$ awk 'length($0) > 10' geeksforgeeks.txt
Tarun A12 1 Praveen M42 3
7) Чтобы найти / проверить любую строку в любом столбце:
$ awk '{ if($3 == "B6") print $0;}' geeksforgeeks.txt
8) Чтобы напечатать квадраты первых чисел от 1 до n, скажем 6:
$ awk 'BEGIN { for(i=1;i<=6;i++) print "square of", i, "is",i*i; }'
square of 1 is 1 square of 2 is 4 square of 3 is 9 square of 4 is 16 square of 5 is 25 square of 6 is 36
Эта статья предоставлена Аншикой Гоял и Правином Неги . Если вы как GeeksforGeeks и хотели бы внести свой вклад, вы также можете написать статью с помощью contribute.geeksforgeeks.org или по почте статьи [email protected]. Смотрите свою статью, появляющуюся на главной странице GeeksforGeeks, и помогите другим вундеркиндам.
Пожалуйста, пишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по обсуждаемой выше теме.
Рекомендуемые посты:
Команда AWK в Unix / Linux с примерами
0.00 (0%) 0 votes
Примеры команды AWK в Linux
В этой статье мы покажем вам некоторые практические примеры того, как использовать AWK на VPS на базе Linux.
Введение
AWK назван в честь фамилии его авторов: Альфред Ахо, Питер Вайнбергером и Брайан Керниган. AWK очень полезный язык сценариев для обработки текста. Этот язык выполняется в интерпретаторе. Это позволяет пользователю обрабатывать некоторые входные, определять переменные, использовать логические операторы, строки и числовые функции, извлечения данных и создания отформатированных отчетов. Синтаксис AWK очень близок с языку C и является прямым предшественником Perl. Все сценарии AWK могут быть преобразованы в сценарии Perl с использованием утилиты A2P.
Предпосылки
Интерпретатор AWK является стандартным инструментом, найденным на каждом дистрибутиве Linux. Пакет gawk содержит версию AWK с открытым исходным кодом, и в зависимости от дистрибутива Linux он может быть установлен из исходного файла или с помощью пакетов gawk или mawk, включенных в конкретный дистрибутив Linux.
Установка
Войдите на сервер через SSH с правами суперпользователя
ssh root@IP_Address
Для того, чтобы установить утилиту командной строки AWK на CentOS/Fedora или на любую другую на основе RPM распределения Linux, выполните следующую команду:
yum install gawk
В Ubuntu/Debian, вам нужно вызвать эту команду, чтобы установить Gawk:
apt-get install gawk
Примеры команды AWK
Простые команды awk могут быть легко запущены из командной строки, а для более сложных задач должны быть записаны в виде сценариев awk в файл. Ниже перечислены некоторые полезные примеры команд awk и исполняемых скриптов.
Вы можете использовать команду AWK для печати только определенных столбцов из поля ввода. Например, с помощью команды приведенной ниже вы можете узнать список IP-адресов, которые подключены к серверу:
netstat -anp|grep tcp|awk '{print $5}'| cut -d : -f1 | sort | uniq -c | sort -n
Это очень полезно, если вы расследуете, находиться ли ваш сервер под атакой DoS или DDoS.
В следующем примере мы используем AWK для поиска конкретного шаблона в определенных столбцах и делаем какое-то действие, на основе результата:
exim -bpr | grep frozen | awk {'print $3'} | xargs exim -Mrm
Выше команда удалит все замороженные сообщения электронной почты из почтовой очереди Exim.
AWK часто используется для выполнения полезной и практической обработки и манипуляции текста. Например, мы можем использовать AWK для удаления дубликатов в текстовом файле без сортировки:
awk '!x[$0]++' file-with-duplicates > new-file-without-duplicates
Следующая команда напечатает пять случайных чисел от 0 до 999:
awk 'BEGIN { for (i = 1; i <= 5; i++) print int(1000 * rand()) }'
Используйте следующую команду, чтобы подсчитать количество строк в файле с именем «sample_file»:
awk 'END { print NR }' sample_file
Следующая команда выведет все строки в файле «sample_file», которые содержат строки, начинающиеся с ‘ A ‘ или ‘a’, за которыми следует ‘ re’:
awk '/[Aa]re/{print}' /opt/sample_file
Вы можете использовать команду AWK для более сложных операций. Если ваш веб-сайт работает довольно медленно, вы можете использовать следующую команду, чтобы проверить, есть ли какая-то проблема с диском I/O (и/или сети, в некоторых редких случаях):
tac /proc/stat | awk '/^btime/ {up=systime()-$2;print "up " up/86400 "d"}; /^cpu / {print "user " $2/up "%, nice " $3/up "%, sys " $4/up "%, idle " $5/up "%, iowait " $6/up "%, steal " $9/up "%\niowait/used " $6 / ($2+$3+$4) ", steal/used " $9 / ($2+$3+$4) }'
IOWAIT означает, как долго процессы блокируются занятые вводом/выводом, в основном дискового хранения или, возможно, сети. STEAL означает, как долго процессы блокируются удачей CPU Time slice на сервере. Выше iowait на время процессора пользователя (=USER + NICE + SYSTEM) показывает занят ввода / вывода, выше украсть просматривается показывает занят CPU.
Следующий сценарий использует простую команду awk, которая выполняет поиск во входном файле ‘/etc/passwd ‘ и предоставляет вывод с именем пользователя, за которым следует дата и время последнего входа:
vi login-check
#!/bin/bash for user in `awk -F: '{print $1}' /etc/passwd` do echo -n "$user: " finger $user | grep Last if [ $? != 0 ]; then echo fi done
Сделайте скрипт исполняемым:
chmod 755 login-check
Выполните скрипт:
./login-check
Вы должны состоянии увидеть учетные записи пользователей, доступных на сервере, а затем по дате и времени последнего входа в систему каждого пользователя.
Вывод
Есть некоторые новые языки, такие как Perl и Python, которые могут быть использованы вместо AWK, но использование AWK имеет ряд преимуществ, так как:
- AWK очень легко узнать.
- AWK может быть использован для решения определенных типов задач быстрее и создавать более эффективные сценарии, чем при использовании других инструментов/языков.
- AWK очень удобен при работе с большими файлами, как журналы и т.д., потому что с помощью команды/скрипа AWK вы можете создать отфильтрованный и удобочитаемый отчет.
Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.
практические примеры / Блог компании RUVDS.com / Хабр
Bash-скрипты: начало
Bash-скрипты, часть 2: циклы
Bash-скрипты, часть 3: параметры и ключи командной строки
Bash-скрипты, часть 4: ввод и вывод
Bash-скрипты, часть 5: сигналы, фоновые задачи, управление сценариями
Bash-скрипты, часть 6: функции и разработка библиотек
Bash-скрипты, часть 7: sed и обработка текстов
Bash-скрипты, часть 8: язык обработки данных awk
Bash-скрипты, часть 9: регулярные выражения
Bash-скрипты, часть 10: практические примеры
Bash-скрипты, часть 11: expect и автоматизация интерактивных утилит
В предыдущих материалах мы обсуждали различные аспекты разработки bash-скриптов, говорили о полезных инструментах, но до сих пор рассматривали лишь небольшие фрагменты кода. Пришло время более масштабных проектов. А именно, здесь вы найдёте два примера. Первый — скрипт для отправки сообщений, второй пример — скрипт, выводящий сведения об использовании дискового пространства.
Главная ценность этих примеров для тех, кто изучает bash, заключается в методике разработки. Когда перед программистом встаёт задача по автоматизации чего бы то ни было, его путь редко бывает прямым и быстрым. Задачу надо разбить на части, найти средства решения каждой из подзадач, а потом собрать из частей готовое решение.
Отправка сообщений в терминал пользователя
В наши дни редко кто прибегает к одной из возможностей Linux, которая позволяет общаться, отправляя сообщения в терминалы пользователей, вошедших в систему. Сама по себе команда отправки сообщений, write
, довольно проста. Для того, чтобы ей воспользоваться, достаточно знать имя пользователя и имя его терминала. Однако, для успешной отправки сообщения, помимо актуальных данных о пользователе и терминале, надо знать, вошёл ли пользователь в систему, не запретил ли он запись в свой терминал. В результате, перед отправкой сообщения нужно выполнить несколько проверок.
Как видите, задача: «отправить сообщение», при ближайшем рассмотрении, оказалась задачей: «проверить возможность отправки сообщения, и, если нет препятствий, отправить его». Займёмся решением задачи, то есть — разработкой bash-скрипта.
▍Команды who и mesg
Ядром скрипта являются несколько команд, которые мы ещё не обсуждали. Всё остальное должно быть вам знакомо по предыдущим материалам.
Первое, что нам тут понадобится — команда who
. Она позволяет узнать сведения о пользователях, работающих в системе. В простейшем виде её вызов выглядит так:
$ who
Результаты вызова команды who
В каждой строчке, которую выводит команда who
, нас интересуют первых два показателя — имя пользователя и сведения о его терминале.
По умолчанию запись в терминал разрешена, но пользователь может, с помощью команды mesg
, запретить отправку ему сообщений. Таким образом, прежде чем пытаться что-то кому-то отправить, неплохо будет проверить, разрешена ли отправка сообщений. Если нужно узнать собственный статус, достаточно ввести команду mesg
без параметров:
$ mesg
Команда mesg
В данном случае команда вывела «is y», это значит, что пользователь, под которым мы работаем в системе, может принимать сообщения, отправленные в его терминал. В противном случае mesg
выведет «is n».
Для проверки того, разрешена ли отправка сообщений какому-то другому пользователю, можно использовать уже знакомую вам команду who
с ключом -T
:
$ who -T
При этом проверка возможна только для пользователей, которые вошли в систему. Если такая команда, после имени пользователя, выведет чёрточку (-), это означает, что пользователь запретил запись в свой терминал, то есть, сообщения ему отправлять нельзя. О том, что пользователю можно отправлять сообщения, говорит знак «плюс» (+).
Если у вас приём сообщений отключён, а вы хотите позволить другим пользователям отправлять вам сообщения, можно воспользоваться такой командой:
$ mesg y
Включение приёма сообщений от других пользователей
После включения приёма сообщений mesg
возвращает «is y».
Конечно, для обмена сообщениями нужны два пользователя, поэтому мы, после обычного входа в систему, подключились к компьютеру по ssh. Теперь можно поэкспериментировать.
▍Команда write
Основной инструмент для обмена сообщениями между пользователями, вошедшими в систему — команда write
. Если приём сообщений у пользователя разрешён, с помощью этой команды ему можно отправлять сообщения, используя его имя и сведения о терминале.
Обратите внимание на то, что с помощью write
можно отправлять сообщения пользователям, вошедшим в виртуальную консоль. Пользователи, которые работают в графическом окружении (KDE, Gnome, Cinnamon, и так далее), не могут получать подобные сообщения.
Итак, мы, работая под пользователем likegeeks
, инициируем сеанс связи с пользователем testuser
, который работает в терминале pts/1
, следующим образом:
$ write testuser pts/1
Проверка возможности отправки сообщений и отправка сообщения
После выполнения вышеуказанной команды перед нами окажется пустая строка, в которую нужно ввести первую строку сообщения. Нажав клавишу ENTER
, мы можем ввести следующую строку сообщения. После того, как ввод текста завершён, окончить сеанс связи можно, воспользовавшись комбинацией клавиш CTRL + D
, которая позволяет ввести символ конца файла.
Вот что увидит в своём терминале пользователь, которому мы отправили сообщение.
Новое сообщение, пришедшее в терминал
Получатель может понять от кого пришло сообщение, увидеть время, когда оно было отправлено. Обратите внимание на признак конца файла, EOF
, расположенный в нижней части окна терминала. Он указывает на окончание текста сообщения.
Полагаем, теперь у нас есть всё необходимое для того, чтобы автоматизировать отправку сообщений с помощью сценария командной строки.
▍Создание скрипта для отправки сообщений
Прежде чем заниматься отправкой сообщений, нужно определить, вошёл ли интересующий нас пользователь в систему. Сделать это можно с помощью такой команды:
logged_on=$(who | grep -i -m 1 $1 | awk '{print $1}')
Здесь результаты работы команды who
передаются команде grep
. Ключ -i
этой команды позволяет игнорировать регистр символов. Ключ -m 1
включён в вызов команды на тот случай, если пользователь вошёл в систему несколько раз. Эта команда либо не выведет ничего, либо выведет имя пользователя (его мы укажем при вызове скрипта, оно попадёт в позиционную переменную $1
), соответствующее первому найденному сеансу. Вывод grep
мы передаём awk
. Эта команда, опять же, либо не выведет ничего, либо выведет элемент, записанный в собственную переменную $1
, то есть — имя пользователя. В итоге то, что получилось, попадает в переменную logged_on
.
Теперь надо проверить переменную logged_on
, посмотреть, есть ли в ней что-нибудь:
if [ -z $logged_on ]
then
echo "$1 is not logged on."
echo "Exit"
exit
fi
Если вы не вполне уверенно чувствуете себя, работая с конструкцией if
, взгляните на этот материал.
Скрипт, содержащий вышеописанный код, сохраним в файле senderscript
и вызовем, передав ему, в качестве параметра командной строки, имя пользователя testuser
.
Проверка статуса пользователя
Тут мы проверяем, является ли logged_on
переменной с нулевой длиной. Если это так, нам сообщат о том, что в данный момент пользователь в систему не вошёл и скрипт завершит работу с помощью команды exit
. В противном случае выполнение скрипта продолжится.
▍Проверка возможности записи в терминал пользователя
Теперь надо проверить, принимает ли пользователь сообщения. Для этого понадобится такая конструкция, похожая на ту, которую мы использовали выше:
allowed=$(who -T | grep -i -m 1 $1 | awk '{print $2}')
if [ $allowed != "+" ]
then
echo "$1 does not allowing messaging."
echo "Exit"
exit
fi
Проверка возможности отправки сообщений пользователю
Сначала мы вызываем команду who
с ключом -T
. В строке сведений о пользователе, который может принимать сообщения, окажется знак «плюс» (+), если же пользователь принимать сообщения не может — там будет чёрточка (-). То, что получилось после вызова who
, передаётся grep
, а потом — awk
, формируя переменную allowed
.
Далее, используя условный оператор, мы проверяем то, что оказалось в переменной allowed
. Если знака «плюс» в ней нет, сообщим о том, что отправка сообщений пользователю запрещена и завершим работу. В противном случае выполнение сценария продолжится.
▍Проверка правильности вызова скрипта
Первым параметром скрипта является имя пользователя, которому мы хотим отправить сообщение. Вторым — текст сообщения, в данном случае — состоящий из одного слова. Для того, чтобы проверить, передано ли скрипту сообщение для отправки, воспользуемся таким кодом:
if [ -z $2 ]
then
echo "No message parameter included."
echo "Exit"
exit
fi
Проверка параметров командной строки, указанных при вызове скрипта
Тут, если при вызове скрипта ему не было передано сообщение для отправки, мы сообщаем об этом и завершаем работу. В противном случае — идём дальше.
▍Получение сведений о терминале пользователя
Прежде чем отправить пользователю сообщение, нужно получить сведения о терминале, в котором он работает и сохранить имя терминала в переменной. Делается это так:
terminal=$(who | grep -i -m 1 $1 | awk '{print $2}')
Теперь, после того, как все необходимые данные собраны, осталось лишь отправить сообщение:
echo $2 | write $logged_on $terminal
Вызов готового скрипта выглядит так:
$ ./senderscript testuser welcome
Успешная отправка сообщения с помощью bash-скрипта
Как видно, всё работает как надо. Однако, с помощью такого сценария можно отправлять лишь сообщения, состоящие из одного слова. Хорошо бы получить возможность отправлять более длинные сообщения.
▍Отправка длинных сообщений
Попробуем вызвать сценарий senderscript
, передав ему сообщение, состоящее из нескольких слов:
$ ./senderscript likegeeks welcome to shell scripting
Попытка отправки длинного сообщения
Как видно, отправлено было лишь первое слово. Всё дело в том, что каждое слово сообщения воспринимается внутри скрипта как отдельная позиционная переменная. Для того, чтобы получить возможность отправки длинных сообщений, обработаем параметры командной строки, переданные сценарию, воспользовавшись командой shift
и циклом while
.
shift
while [ -n "$1" ]
do
whole_message=$whole_message' '$1
shift
done
После этого, в команде отправки сообщения, воспользуемся, вместо применяемой ранее позиционной переменной $2
, переменной whole_message
:
echo $whole_message | write $logged_on $terminal
Вот полный текст сценария:
#!/bin/bash
logged_on=$(who | grep -i -m 1 $1 | awk '{print $1}')
if [ -z $logged_on ]
then
echo "$1 is not logged on."
echo "Exit"
exit
fi
allowed=$(who -T | grep -i -m 1 $1 | awk '{print $2}')
if [ $allowed != "+" ]
then
echo "$1 does not allowing messaging."
echo "Exit"
exit
fi
if [ -z $2 ]
then
echo "No message parameter included."
echo "Exit"
exit
fi
terminal=$(who | grep -i -m 1 $1 | awk '{print $2}')
shift
while [ -n "$1" ]
do
whole_message=$whole_message' '$1
shift
done
echo $whole_message | write $logged_on $terminal
Испытаем его:
$ ./senderscript likegeeks welcome to shell scripting
Успешная отправка длинного сообщения:
Длинное сообщение успешно дошло до адресата. Теперь рассмотрим следующий пример.
Скрипт для мониторинга дискового пространства
Сейчас мы собираемся создать сценарий командной строки, который предназначен для поиска в заданных директориях первой десятки папок, на которые приходится больше всего дискового пространства. В этом нам поможет команда du
, которая выводит сведения о том, сколько места на диске занимают файлы и папки. По умолчанию она выводит сведения лишь о директориях, с ключом -a
в отчёт попадают и отдельные файлы. Её ключ -s
позволяет вывести сведения о размерах директорий. Эта команда позволяет, например, узнать объём дискового пространства, который занимают данные некоего пользователя. Вот как выглядит вызов этой команды:
$ du -s /var/log/
Для наших целей лучше подойдёт ключ -S
(заглавная S), так как он позволяет получить сведения как по корневой папке, так и по вложенным в неё директориям:
$ du -S /var/log/
Вызов команды du с ключами -s и -S
Нам нужно найти директории, на которые приходится больше всего дискового пространства, поэтому список, который выдаёт du
, надо отсортировать, воспользовавшись командой sort
:
$ du -S /var/log/ | sort -rn
Отсортированный список объектов
Ключ -n
указывает команде на то, что нужна числовая сортировка, ключ -r —
на обратный порядок сортировки (самое большое число окажется в начале списка). Полученные данные вполне подходят для наших целей.
Для того, чтобы ограничить полученный список первыми десятью записями, воспользуемся потоковым редактором sed
, который позволит удалить из полученного списка все строки, начиная с одиннадцатой. Следующий шаг — добавить к каждой полученной строке её номер. Тут также поможет sed
, а именно — его команда N
:
sed '{11,$D; =}' |
sed 'N; s/\n/ /' |
Приведём полученные данные в порядок, воспользовавшись awk
. Передадим awk
то, что получилось после обработки данных с помощью sed
, применив, как и в других случаях, конвейер, и выведем полученные данные с помощью команды printf
:
awk '{printf $1 ":" "\t" $2 "\t" $3 "\n"}'
В начале строки выводится её номер, потом идёт двоеточие и знак табуляции, далее — объём дискового пространства, следом — ещё один знак табуляции и имя папки.
Соберём вместе всё то, о чём мы говорили:
$ du -S /var/log/ |
sort -rn |
sed '{11,$D; =}' |
sed 'N; s/\n/ /' |
awk '{printf $1 ":" "\t" $2 "\t" $3 "\n"}'
Вывод сведений о дисковом пространстве
Для того, чтобы повысить эффективность работы скрипта, код которого вы совсем скоро увидите, реализуем возможность получения данных сразу по нескольким директориям. Для этого создадим переменную MY_DIRECTORIES
и внесём в неё список интересующих нас директорий:
MY_DIRECTORIES="/home /var/log"
Переберём список с помощью цикла for
и вызовем вышеописанную последовательность команд для каждого элемента списка. Вот что получилось в результате:
#!/bin/bash
MY_DIRECTORIES="/home /var/log"
echo "Top Ten Disk Space Usage"
for DIR in $MY_DIRECTORIES
do
echo "The $DIR Directory:"
du -S $DIR 2>/dev/null |
sort -rn |
sed '{11,$D; =}' |
sed 'N; s/\n/ /' |
awk '{printf $1 ":" "\t" $2 "\t" $3 "\n"}'
done
exit
Получение сведений о нескольких директориях
Как видите, скрипт выводит, в виде удобного списка, сведения о директориях, список которых хранится в MY_DIRECTORIES
.
Команду du
в этом скрипте можно вызвать с другими ключами, полученный список объектов вполне можно отфильтровать, в целом — тут открывается широкий простор для самостоятельных экспериментов. В результате, вместо работы со списком папок, можно, например, найти самые большие файлы с расширением .log,
или реализовать более сложный алгоритм поиска самых больших (или самых маленьких) файлов и папок.
Итоги
Сегодня мы подробно разобрали пару примеров разработки скриптов. Тут хотелось бы напомнить, что наша главная цель — не в том, чтобы написать скрипт для отправки сообщений с помощью команды write
, или сценарий, который помогает в поиске файлов и папок, занимающих много места на диске, а в описании самого процесса разработки. Освоив эти примеры, поэкспериментировав с ними, возможно — дополнив их или полностью переработав, вы научитесь чему-то новому, улучшите свои навыки разработки bash-скриптов.
На сегодня это всё. В следующий раз поговорим об автоматизации работы с интерактивными утилитами с помощью expect.
Уважаемые читатели! Есть ли у вас на примете несложные (а может быть и сложные, но понятные) bash-скрипты, разбор которых будет полезен новичкам?
Команда AWK | Основы BASH
Когда я только начинал работать системным администратором и хотел узнать, что нужно для повышения , мне сказали, что мне нужно знать утилиты BASH, такие как AWK. Я не уверен, что AWK на самом деле является утилитой — он изначально задумывался как язык программирования, управляемый данными, когда его написали в Bell Labs Альфред Ахо, Питер Вайнбергер и Брайан Керниган. Название происходит от инициалов их фамилий, но программа, которую мы используем в BASH в Linux, — это (G) AWK или Gnu AWK, и есть много производных. Что можно делать с AWK? Теперь, когда у нас есть мелочи, что мы можем сделать с AWK? AWK можно вызвать из командной строки, просто набрав awk
. В командной строке все в нижнем регистре. AWK чаще всего используется для обработки файлов. AWK обрабатывает условие, если оно предусмотрено, а затем выполняет действие. Действие по умолчанию — распечатать все, что соответствует критериям условия. Чтобы найти в файле совпадение с шаблоном регулярного выражения:
awk ‘/ regex /’ / etc / passwd
В результате в командной строке будут напечатаны совпадающие строки из файла / etc / passwd
.Это довольно просто, и мы используем поведение по умолчанию при печати совпадений. AWK также можно использовать для поиска столбцов данных и четкого вывода информации. Чтобы узнать, запущена ли конкретная служба, и отобразить имя, если оно находится:
ps -ax | awk ‘/ systemd / {print $ 5}’
Одна из приятных особенностей awk
заключается в том, что он токенизирует строки, которые в него вводятся. Это означает, что для элементов, у которых есть разделитель, вы можете выбрать столбец. Вы можете указать разделитель полей в командной строке.Одним из примеров может быть печать списка пользователей из / etc / passwd
, записи разделены двоеточием (:
), а имя пользователя находится в первом столбце. Помните, что $ 0
— это вся строка.
awk -F: ‘{print $ 1}’ / etc / passwd
Запуск AWK Это здорово, но мы хотим поработать с AWK, верно? Итак, если у вас есть каталог (для этого мы будем использовать / etc
) и вы хотите узнать размер этого каталога:
ls -l / etc | awk '{x + = $ 5} END {print «total bytes:» x}'
Здесь мы берем вывод команды ls -l
и добавляем каждую строку к переменной x
, поскольку переменные в AWK инициализируются как 0
, а пятый столбец — это размер файла, который мы добавляем к размеру каждого файла до x
при синтаксическом анализе вывода.Ключевое слово END
указывает действие, которое мы хотим предпринять после завершения анализа ввода. В этом случае мы печатаем значение x
. В килобайтах мы делим результат x
на 1024:
ls -l / etc | awk '{x + = $ 5} END {print «total Kilobytes:» (x / 1024)}
AWK также может использоваться как полноценный язык сценариев, и вы можете передавать ему файлы сценариев в командной строке, используя -f
флаг. Возможно, мы поговорим об этом в одном из будущих постов в блоге. С чего начать Как я сказал в начале, использование командной строки — это то, что действительно отделяет людей от их современников, когда дело доходит до собеседований. Компании занимаются автоматизацией и всем как код. Все начинается со знания оболочки Bash и всех ее функций. Если вы хотите выделиться и показать, что вам комфортно в том, что вы делаете, вы можете подумать о том, чтобы взглянуть на Руководство администратора по сценариям Bash. Это перенесет вас в место, где вы действительно сможете показать свой уровень комфорта с помощью командной строки.
.
|
|
.
bash — Использование переменных awk вне команды awk
Переполнение стека
- Около
Продукты
- Для команд
Переполнение стека
Общественные вопросы и ответыПереполнение стека для команд
Где разработчики и технологи делятся частными знаниями с коллегамиВакансии
Программирование и связанные с ним технические возможности карьерного ростаТалант
Нанимайте технических специалистов и создавайте свой бренд работодателяРеклама
Обратитесь к разработчикам и технологам со всего мира- О компании
.