Преобразование раздела конфигурации маршрутизатора в CSV-файл с помощью Bash - PullRequest
2 голосов
/ 02 октября 2019

Похоже на мой предыдущий вопрос , но в пример файла конфигурации добавлены дополнительные элементы.

У меня есть файл конфигурации с повторяющимися группами строк (но разным количеством строк в группе), который я хочу объединить в одну строку CSV для упрощения импорта в базу данных. (Структура базы данных является гибкой).

# Example: 
    lag 1
        description "LAG-1 GOES TO LAG-2"
        port 1/2/1 
        port 1/2/2 
        port 3/2/3 
        lacp active administrative-key 32770
    exit
    lag 10
        description "REMOVED-LAG-10-0.0.0.0"
        port 4/1/1 
        port 5/1/1
        lacp active administrative-key 32771
    exit
    lag 11
        description "REMOVED-LAG-11-4.4.4.4"
        port 5/1/2 
        lacp active administrative-key 32772
    exit

В конечном итоге мне нужно получить строки с разделением запятыми для каждого блока между "lag" и "exit", например:

1,"LAG 1 GOES TO LAG-2",32770,1/2/3
1,"LAG 1 GOES TO LAG-2",32770,1/2/2
1,"LAG 1 GOES TO LAG-2",32770,3/2/3 
10,"REMOVED-LAG-10-0.0.0.0",32771,4/1/1
10,"REMOVED-LAG-10-0.0.0.0",32771,5/1/1
11,"REMOVED-LAG-11-4.4.4.4",32772,5/1/2 

Затем я импортирую вТаблица, подобная этой:

lag-id | description | key | port

Я пробовал различные находящиеся здесь awk-однострочные, такие как:

awk -v RS="lag" 'NR>1{$1=$1; print RS, $0}' 

, но кажется, что линии сжимаются по вертикали, поэтому яв конечном итоге с

 exit 3/2/3  "LAG 1 GOES TO LAG-2"
 exit 4/2/3  "LAG 10 GOES TO LAG-3"
 exit 4/1/1  "LAG 11 GOES TO LAG-21"

Ответы [ 2 ]

1 голос
/ 02 октября 2019
$ cat tst.awk
BEGIN { OFS="," }
{
    tag = $1
    val = ( match($0,/"[^"]*"/) ? substr($0,RSTART,RLENGTH) : $NF )

    if ( tag == "port" ) {
        ports[++numPorts] = val
    }
    else {
        vals[++numVals] = val
    }
}

tag == "exit" {
    for (portNr=1; portNr<=numPorts; portNr++) {
        for (valNr=1; valNr<numVals; valNr++) {
            printf "%s%s", vals[valNr], OFS
        }
        print ports[portNr]
    }
    numPorts = numVals = 0
}

$ awk -f tst.awk file
1,"LAG-1 GOES TO LAG-2",32770,1/2/1
1,"LAG-1 GOES TO LAG-2",32770,1/2/2
1,"LAG-1 GOES TO LAG-2",32770,3/2/3
10,"REMOVED-LAG-10-0.0.0.0",32771,4/1/1
10,"REMOVED-LAG-10-0.0.0.0",32771,5/1/1
11,"REMOVED-LAG-11-4.4.4.4",32772,5/1/2
0 голосов
/ 02 октября 2019

Не могли бы вы попробовать следующее. (Поскольку я написал это на мобильном телефоне, поэтому не смог проверить это, но должно работать)

awk -v OFS=","  '
{
  gsub(/\r/,"")
  sub(/^ +/,"")
}
/lag/{
  ind=$2
  next
}
/description/ && match($0,/\".*\"/){ 
 desc=substr($0,RSTART,RLENGTH)
 next
}
/port/{
 a[++count]=$2
 next
}
/lacp active/{
 for(j=1;j<=count;j++){
   print Ind,desc,$NF,a[j]
 }
 count=""
 delete a
}
'  Input_file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...