Практическая работа: Модуль 7. Работа с текстовой информацией

См. также Требования, правила и цели выполнения практической работы

Практические задания

В рамках этого модуля мы предлагаем выполнить расширенную лабораторную работу.

Задание 1.

Создайте текстовый файл sample со следующим содержанием:

Добрый день, Петр Васильев!

Рамки и место обучения кадров представляют собой интересный эксперимент
проверки дальнейших направлений развития см. Рис 10. Идейные соображения
высшего порядка, а также консультация с широким активом способствуют
подготовке и реализации дальнейших направлений развития по стандарту
ISO-9001. Не следует, однако, забывать, что рамки и место обучения кадров
способствуют подготовке и реализации модели развития.
Повседневная практика показывает, что укрепление и развитие структуры
требуют определения и уточнения системы обучения кадров, соответствует
насущным потребностям.

Задание 2.

Создайте еще один файл «sign» с подписью:

Пишите нам на email: info@company.lan
Мобильный: +79881112230
Офисный многоканальный: 8 800 2201100
Сайт: www.company.lan

Задание 3.

Выведите текст письма в стандартный поток вывода.

Задание 4.

Выведите содержимое двух файлов на экран подряд одной командой.

Задание 5.

Найдите количество строк в файле.

Задание 6.

Выведите первую строку из файла sample.

Задание 7.

Найдите имя в первом предложении и удалите у имени пробел.

Задание 8.

Выведите содержимое файлов «sample» и «sign» на экран, пронумеруйте строки при выводе.

Задание 9.

Объедините содержимое файлов «sample» и «sign» и запишите его в новый файл «message».

Задание 10.

Выведите на стандартный поток вывода только последнюю строку файла «message».

Задание 11.

Выведите на стандартный поток вывода номер рисунка из файла «message». Используйте для этого команду grep и регулярное выражение.

Задание 12.

Выведите на стандартный поток вывода адрес электронной почты из файла «message».

Подсказка

Будем считать, что адрес email состоит только из букв, цифр, дефисов, точек, подчёркиваний и знака «@». Поиск всех возможных вариантов адреса электронной почты может оказаться весьма непростой задачей: https://stackoverflow.com/questions/46155/how-can-i-validate-an-email-address-in-javascript/1373724#1373724

Задание 13.

Выведите на стандартный поток вывода номер 8 800 из файла «message».

Задание 14.

Выведите на стандартный поток вывода интернациональные телефонные номера из файла «message».

Задание 15.

Удалите два и более пробелов из файла «message».

Ответы на практические задания (пошаговые инструкции)

Задание 1.

Откроем файл sample в редакторе nano командой nano letter и наполним его следующим содержанием:

Добрый день, Петр Васильев!

Рамки и место обучения кадров представляют собой интересный эксперимент
проверки дальнейших направлений развития см. Рис 10. Идейные соображения
высшего порядка, а также консультация с широким активом способствуют
подготовке и реализации дальнейших направлений развития по стандарту
ISO-9001. Не следует, однако, забывать, что рамки и место обучения кадров
способствуют подготовке и реализации модели развития.
Повседневная практика показывает, что укрепление и развитие структуры
требуют определения и уточнения системы обучения кадров, соответствует
насущным потребностям.

Задание 2.

Создадим еще один файл sign с подписью nano sign.

Пишите нам на email: info@company.lan
Мобильный: +79881112230
Офисный многоканальный: 8 800 2201100
Сайт: www.company.lan

Задание 3.

Выведем текст письма в стандартный поток вывода, который затем печатается в консоли.

cat letter

Задание 4.

Выведем оба файла на экран подряд с помощью команды cat, которая склеивает файлы:

cat letter sign

Задание 5.

Найдем количество строк в файле.

cat letter sign | wc -l

Задание 6.

Найдем первую строку в файле sample.

cat letter | head -1

Задание 7.

Найдем имя в первом предложении и удалим у имени пробел:

cat letter | head -1 | cut -d',' -f 2 | xargs

Задание 8.

Сгруппируем стандартные выводы.

(cat letter; echo -e "\n__"; cat sign)

Пронумеруем вывод и посмотрим, как прошло слияние группировкой.

(cat letter; echo -e "\n__"; cat sign) | nl

Такую технику можно использовать для генерации заголовков колонок, а затем данных.

(echo "col1;col2;col3"; echo "val2;val2;val2"; echo "val3;val3;val3") | column -t -s';'

Задание 9.

Данная группировка позволяет объединить несколько текстовых блоков для дальнейшей обработки.

(cat letter; echo -e "\n__"; cat sign) | tee message

Задание 10.

Найдем последнюю строку в файле message.

cat message | tail -1

Команда tail может следить за логами tail -f.

sudo tail -f /var/log/auth.log
  1. Нажмем пару раз <Enter> для разделения информации (для разделения старой информации от новой).

  2. Откроем новую вкладку терминала ALT+T.

  3. Перейдем в сессию root sudo -i.

  4. Закроем новую сессию командой exit.

  5. Мы увидим изменение в первом окне команды tail -f.

  6. Завершим tail -f сочетанием клавиш Ctrl+C.

Команда tee создает и выводит файл, удобна для создания конфигурационных файлов с применением sudo.

(echo "[main]"; echo 'key1*value'; echo "key2*value") | sudo tee /etc/test.ini

Задание 11.

Вернемся к сообщению и найдем номер рисунка:

cat message | grep -Eo 'Рис\s[0-9]{1,10}' | cut -d' ' -f 2

Задание 12.

Вернемся к сообщению и найдем email:

cat message | grep -Eo '([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)'

В качестве вспомогательного инструмента воспользуйтесь https://regex101.com/r/hrIiGz/1.

Задание 13.

Вернемся к сообщению, найдем номер 8 800.

cat message | grep -Eo '8\s800\s[0-9]{1,10}'

В качестве вспомогательного инструмента воспользуйтесь https://regex101.com/r/2dURa1/1.

Задание 14.

Найдем интернациональные телефонные номера:

cat message | grep -Eo '\+?[1-9][0-9]{7,14}'

В качестве вспомогательного инструмента воспользуйтесь https://regex101.com/r/cCfkrI/1.

Задание 15.

Удалим два и более пробелов.

cat message | sed 's/ \{1,\}/ /g'

В качестве вспомогательного инструмента воспользуйтесь https://regex101.com/r/p2YkJB/1.

Дополнительные упражнения

Конфигурационные файлы

  • Выведем конфигурацию локальной петли 127.

cat /etc/hosts | grep ^127
  • Видим, что разделитель пробел и можно вывести полное имя.

cat /etc/hosts | grep ^127 | cut -d' ' -f 2

Команда grep нашла ip 127, а cut вырезала второе поле по разделителю пробел.

  • Посмотрим локализацию по умолчанию.

cat /etc/default/locale | cut -d"*" -f 2 | tr -d "\""
  • Удалим комментарий с символа #.

cat /etc/default/locale | grep -v '#' | cut -d"*" -f 2 | tr -d "\""

Командой tr мы удалили кавычки для дальнейшей работы.

Текстовые файлы с разделителем CSV

Создадим в Libreoffce Calc таблицу.

табл. 2 Содержимое users.csv

Пользователь

Имя

Фамилия

ivani

Иван

Иванов

ivani

Иван

Иванченко

alexa

Алексей

Антонов

Сохраним как ~/users.csv с разделителем запятые.

  • Выведем файл cat users.csv. Должен получиться такой файл:

Пользователь,Имя,Фамилия
ivani,Иван,Иванов
ivani,Иван,Иванченко
alexa,Алексей,Антонов
  • Выведем файл в табличном виде.

cat users.csv | column -t -s,
  • Выведем заголовок с названиями колонок.

grep $(head -1 users.csv) users.csv
  • Выведем уникальных и отсортированных пользователей, которых необходимо создать.

grep -v $(head -1 users.csv) users.csv | cut -d"," -f 1 | sort | uniq
  • Запустим команду xargs для создания локальных пользователей по списку.

grep -v $(head -1 users.csv) users.csv | cut -d"," -f 1 | sort | uniq | xargs -I {} sudo useradd {}
  • Проверим наличие локальных пользователей.

grep -v $(head -1 users.csv) users.csv | cut -d"," -f 1 | uniq |
xargs -I {} grep {} /etc/passwd

Данные в Markup Language

Формат XML

Для работы xml нужно установить xpath sudo apt install curl libxml-xpath-perl.

Документация по xpath https://www.w3.org/TR/xpath-30/.

  • Поработаем с https://www.cbr-xml-daily.ru/daily_utf8.xml.

    • Скачаем текущий курс на сайте.

curl -s https://www.cbr-xml-daily.ru/daily_utf8.xml > daily.xml

Утилита curl получает данные из интернета по URL адресу. Их можно сохранить для последующей обработки.

  • Выведем узел с ID * R01235.

xpath -q -e "//Valute[@ID*'R01235']" ./daily.xml
  • Выведем курс доллара в рублях.

xpath -q -e "//Valute[@ID*'R01235']/Value/text()" ./daily.xml

где -e «//Valute[@ID*“R01235“]/Value/text()» это запрос XPath, который применяется для поиска данных в форматах xml/html

Формат JSON

Для работы с JSON потребуется установить утилиту jq с помощью команды sudo apt install jq.

Документация по утилите jq https://jqlang.github.io/jq/manual/.

  • Выведем курс Доллара.

curl -s https://www.cbr-xml-daily.ru/latest.js | jq -r ".rates.USD"
  • Список всех валют.

curl -s https://www.cbr-xml-daily.ru/latest.js | jq -r ".rates | to_entries[] | .key"
  • Список всех валют и значений.

curl -s https://www.cbr-xml-daily.ru/latest.js | jq -r ".rates | to_entries[] | .key, .value"

Формат LDIF

  • Создадим пример данных nano users.ldif.

dn: uid*admin,cn*users,cn*accounts,dc*ald,dc*company,dc*lan
uid: admin
sn: Administrator

dn: uid*oolegov,cn*users,cn*accounts,dc*ald,dc*company,dc*lan
uid: oolegov
sn:: 0J7Qu9C10LPQvtCy

dn: uid*yanaz,cn*users,cn*accounts,dc*ald,dc*company,dc*lan
uid: yanaz
sn:: 0JfRg9Cx0LjQvdCw

Скопируем с пустой строкой в конце файла, т. к. это разделитель записи в LDIF формате.

  • Найдем запись uid*oolegov из users.ldif файла.

cat users.ldif | sed -ne '/^dn: uid*oolegov/,/^$/p'
  • Найдем атрибут uid.

cat users.ldif | sed -ne '/^dn: uid*oolegov/,/^$/p' | grep ^uid
  • Выведем значение uid oolegov.

cat users.ldif | sed -ne '/^dn: uid*oolegov/,/^$/p' | grep '^uid' | cut -d' ' -f 2
  • Выведем фамилию из поля sn, применив base64 -d.

cat users.ldif | sed -ne '/^dn: uid*oolegov/,/^$/p' | grep '^sn' | cut -d' ' -f 2 | base64 -d

Формат YAML

  • Установим бинарный файл yq для архитектуры linux amd64.

sudo wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/bin/yq && sudo chmod +x /usr/bin/yq

Документация по утилите https://mikefarah.gitbook.io/yq/.

  • Создадим файл task.yaml.

- name: Пример переменной Playbook
  hosts: all
  vars:
   login: ivani

tasks:
- name: Добавить пользователя {{ login }}
  ansible.builtin.user:
   name: "{{ login }}"
   state: present
  • Выведем название playbook.

yq '.[0].name' task.yaml
  • Найдем элементы, содержащие .hosts со значением all.

cat task.yaml | yq 'filter(.hosts ** "all")'