# Лабораторная работа №5 "Bash Certification"
---
## **Цели работы:**
- Самостоятельно изучить основы программирования на bash.
- Приобретение навыка обработки документов MS Office bash-скриптом.
---
## Ход работы
### **Задание:** Для выпускников школы срочно нужно заполнить именные грамоты на каждого ребёнка. Разумеется, с помощью bash.
#### Имеется шаблон грамоты (грамота.docx) и список учеников (ФИО.txt)
#### **Результат:** bash-скрипт, который создаёт грамоту в формате docx для каждого ученика.
Итак, для начала стоит посмотреть сами файлы.
1) ФИО.txt
В файле построчно записано по 3 слова - ФИО.

2) грамота.docx
В файле представлен макет грамоты, в котором надо заменить "ФИО" на значение из первого файла.

По началу, была идея заменить строку "ФИО" используя команду "sed", не углубляясь в сам файл. Команда выглядел примерно так:
```bash
for FIO in $(cat ФИО.txt); do sed -i "s/ФИО/$FIO/g" грамота.docx > $FIO.gramota.docx; done
```
Но, данная идея оказалась не рабочей от слова совсем, собраные после грамоты не запускались. Пришлось думать дальше.
Потом вспомнил, что в отличии о формата doc, docx представляет собой архив. Где необходимый текст содержится в файле /word/document.xml



Уже отталкиваясь от этого факта буду работать дальше.
Был придуман следующий алгоритм:
1) Разархивировать макет грамоты и использовать его для дальнейшего создания новых архивов.
2) Проходясь в цикле по каждой строке файла с ФИО, заменять значение "ФИО" в файле **/word/document.xml**.
3) Полученный "документ", заархивировать обратно в docx файл.
По ходу реализации данной идеи возникло достаточно много ошибок и прочех проблем. Окончательный вариант bash-команды выглядит следующим образом:
```bash
unzip грамота.docx -d gramota; IFS=$'\n'; for fio in $(cat ФИО.txt); do cp -R gramota $fio.gramota; sed -i "s/ФИО/$fio/g" $fio.gramota/word/document.xml; cd $fio.gramota/; zip -r $fio.gramota.docx *; cd ../; cp $fio.gramota/$fio.gramota.docx $fio.gramota.docx; rm -rf $fio.gramota/; done; rm -rf gramota
```
Очевидно, это не лучшая реализация, но главное, что она работает.
Все грамоты были создано успешно:



Теперь рассмотрим саму команду подробно:
1) Разархивация макета.
```bash
unzip грамота.docx -d gramota;
```
2) Специальная переменная оболочки "IFS" определяет, как Bash распознает границы слов при разделении последовательности строк символов. По умолчанию IFS представляет собой трехсимвольную строку, состоящую из пробела, табуляции и новой строки. Это значит, что при чтении файла с ФИО, цикл будет проходить не просто по всей строке сразу, а по Имени, Фамилии и Отчеству отдельно - чего нам не нужно. Чтобы исправить это, меняю значение переменной на "новою строку"
```bash
IFS=$'\n';
```
3) Цикл по каждой строке файла ФИО (т.е. по каждой строке ФИО)
```bash
for fio in $(cat ФИО.txt);
```
4) Копирую папку с макетом, для дальнейшего его изменения:
```bash
cp -R gramota $fio.gramota;
```
5) Суть всей команды именно эта часть - замена строки "ФИО" на строку из файла ФИО.txt. Параметр **"-i"** - указывает о сохранении изменений в файл. За замену строки отвечает структура: **"s/[Строка которую будем заменять]/[Строка на которую будет замена]"**
```bash
sed -i "s/ФИО/$fio/g" $fio.gramota/word/document.xml;
```
6) Теперь архивирую макет обратно в docx файл. Не уверен в причине, но если запускал команду **zip** вне самой папки с файлами, то структура docx файла была нарушена: все файлы находились внутри ещё одной папки, чего быть не дложно. Поэтому пришлось входить в папку и выходить из неё.
:::danger

:::
:::success

:::
```bash
cd $fio.gramota/; zip -r $fio.gramota.docx *; cd ../;
```
7) Достаю документ из папки и удаляю всё то, что осталось. (Команда **"done"** - конец цикла). И сразу удаляю архивированый в начале макет грамоты.
```bash
cp $fio.gramota/$fio.gramota.docx $fio.gramota.docx; rm -rf $fio.gramota/; done; rm -rf gramota
```
---
### Заключение
Вероятно, это не самая удачная реализация команды, но она работает!) За время выполнения лабораторной работы столкнулся с множеством мелких проблем (большая из них связана с **"zip"**), но именно этот факт позволил лучше ознакомиться с bash.