Как перебрать вывод и отформатировать результат в новый отчет? - PullRequest
0 голосов
/ 03 июня 2019

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

Вывод в формате:

[header]
attribute1 = integer
attribute2 = integer
[header]
attribute1 = integer
attribute2 = integer
...

Где может быть неизвестное количество строф с теми же двумя атрибутами (с неизвестными целочисленными значениями), но с разными заголовками.

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

[header]
new_attribute = integer
[header]
new_attribute = integer

Я посмотрел на команду read, но я не уверен, как сгенерировать требуемый отчет с ней.

Ответы [ 3 ]

2 голосов
/ 03 июня 2019
while read header &&
      read name1 equal value1 &&
      read name2 equal value2
do
    echo "$header"
    echo "new_attribute = $((value1 + value2))"
done < input.cfg > output.cfg

В этом коде предполагается, что ввод выполняется в точно запрещенном формате.Он не обрабатывает ошибочный ввод надежно: неправильно отформатированные строки, пропущенные строки, неожиданные обратные слэши и т. Д.

1 голос
/ 04 июня 2019

Использование специальной библиотеки намного надежнее.Особенно по сравнению с положением строк, появляющихся непрерывно.

Вот короткий скрипт, написанный на Python.Было бы тривиально добавить тесты для определенных разделов и атрибутов, которые будут игнорироваться или проходить без изменений.

Использование входного файла new.ini:

$ cat test.ini
[header1]
attribute1 = 10
attribute2 = 12
[header2]
attribute1 = 23
attribute2 = 25

и сценария transform_ini.py:

$ cat ini.py
#!/usr/bin/python3
import configparser
config = configparser.ConfigParser()
new_config = configparser.ConfigParser()

new_key = 'new_attribute'

config.read('test.ini')

for section in config.sections():
    val = 0

    for key in config[section]:
        val += int(config[section][key])

    new_config[section] = {}
    new_config[section][new_key] = str(val)

with open('new.ini', 'w') as configfile:
    new_config.write(configfile)

результат равен new.ini:

$ cat new.ini 
[header1]
new_attribute = 22

[header2]
new_attribute = 48

Скрипт поддерживает Mapping Protocol Access и, следовательно, требует Python 3.2 или выше.Я не использую getint(), потому что он, кажется, классифицируется как часть устаревшего API.

Обратите внимание, что ConfigParser.read() закрывает входной файл для вас .

1 голос
/ 04 июня 2019

Пожалуйста, не используйте оболочку для массовой обработки текстовых файлов; это медленно и небезопасно. Мой любимый инструмент для обработки текста - Awk, о котором вы можете узнать больше с man awk.

В awk NR относится к записи номера или номеру строки. % - это «по модулю» или остаток, поэтому, если мы знаем, что существует только три вида записей, мы можем написать тупо нужный сценарий.

Попробуйте awk '{print NR%3, $0}' file, чтобы увидеть структуру.

awk -F ' = ' '                                # Field Separator = space, equals, space
  NR%3 == 1 {print $0}                        # print header
  NR%3 == 2 {i=$2}                            # save second field as i
  NR%3 == 0 {print "new_attribute" FS i+$2}   # print string, field separator, and sum
' file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...