Сопоставление с регулярными выражениями с помощью bash выводит в неправильном порядке - PullRequest
0 голосов
/ 14 января 2019

У меня есть текстовый файл, который нужно обработать, чтобы он возвратил желаемый результат.

hostname ABC1234567
NAME: "Chassis", DESCR: "Nexus5020 Chassis"
PID: N5K-C5020P-BF     , VID: V04 , SN: SSI13390FZT

NAME: "Module 1", DESCR: "40x10GE/Supervisor"
PID: N5K-C5020P-BF     , VID: V04 , SN: JAF1344BHNK

NAME: "Module 2", DESCR: "6x10GE Ethernet Module"
PID: N5K-M1600         , VID: V01 , SN: JAB1228018M

NAME: "Module 3", DESCR: "8x1/2/4G FC Module"
PID: N5K-M1008         , VID: V01 , SN: JAB1231020C

Я пытался использовать регулярное выражение для передачи значения в переменную $ host, но это не удалось на основе выходных данных.

#!/bin/bash

re_descr='DESCR: "([^"]+)"'
re_sn='SN: ([^[:space:]]+)'
re_host='hostname ([^"]+)'

while read -r; do
        if [[ $REPLY =~ $re_descr ]]; then
                descr=${BASH_REMATCH[1]}
                continue
        fi
        if [[ $REPLY =~ $re_sn ]]; then
                sn=${BASH_REMATCH[1]}
        fi
        if [[ $REPLY =~ $re_host ]]; then
                host=${BASH_REMATCH[1]}
        fi
        if [[ $descr && $sn ]]; then
                printf '%s\t%s\n' "$host"-"$descr","$sn"
                unset -v host descr sn
        fi
done < <(cat file.txt)

Прямо сейчас он напечатает

-Nexus5020 Chassis,SSI13390FZT
-40x10GE/Supervisor,JAF1344BHNK
-6x10GE Ethernet Module,JAB1228018M
-8x1/2/4G FC Module,JAB1231020C

Как мне заставить его работать, чтобы он печатался в этом формате

ABC1234567-Nexus5020 Chassis,SSI13390FZT
ABC1234567-40x10GE/Supervisor,JAF1344BHNK
ABC1234567-6x10GE Ethernet Module,JAB1228018M
ABC1234567-8x1/2/4G FC Module,JAB1231020C

1 Ответ

0 голосов
/ 14 января 2019

Это все просто логические ошибки, а не проблемы с самим bash. Сравните со следующим рабочим кодом, который вы можете увидеть в действии на https://ideone.com/mLj5ia:

#!/usr/bin/env bash

re_descr='DESCR: "([^"]+)"'
re_sn='SN: ([^[:space:]]+)'
re_host='hostname ([^"]+)'

while IFS= read -r line; do line=${line%$'\r'}
    [[ $line =~ $re_descr ]] && descr=${BASH_REMATCH[1]}
    [[ $line =~ $re_sn ]]    && sn=${BASH_REMATCH[1]}
    [[ $line =~ $re_host ]]  && host=${BASH_REMATCH[1]}
    if [[ $descr && $sn ]]; then
        printf '%s-%s,%s\n' "$host" "$descr" "$sn"
        descr= sn=
    fi
done
  • Мы не хотим continue после сопоставления descr, потому что sn может быть в одной строке.
  • Вы не хотите unset host (или иначе очищать переменную host между строками вывода), потому что вы хотите повторно использовать одно и то же определение имени хоста.
  • Требуется вывод с тире и запятыми, а не с табуляцией, поэтому не используйте \t в строке printf; и убедитесь, что число %s сигил соответствует количеству аргументов неформатной строки.
  • line=${line%$'\r'} явно удаляет любые возвраты каретки с входа.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...