Tengo un archivo de configuración con grupos de líneas repetidos (pero con un número diferente de líneas en un grupo) que quiero combinar en líneas csv individuales para importar más fácilmente a una base de datos. (La estructura de la base de datos es flexible).

# 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

En última instancia, necesito terminar con líneas separadas por comas para cada bloque entre "retraso" y "salida", así:

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 

Luego importaría a una tabla como esta:

lag-id | description | key | port

He intentado varias frases de awk que encontré aquí, como:

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

Pero eso parece comprimir las líneas verticalmente, así que termino con

 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"

EDITAR: se actualizó ligeramente la configuración, la descripción puede tener números LAG-x dos veces. EDIT 2: Actualización agregando valores lacp para obtener la clave de administrador para cada línea csv.

1
Danny Z 2 oct. 2019 a las 16:43

3 respuestas

La mejor respuesta

Por favor, intente seguir.

awk -v OFS="," '
{
  gsub(/\r/,"")
  sub(/^ +/,"")
}
/lag/{
  ind=$2
  next
} 
/description/ && match($0,/\".*\"/){ 
 des=substr($0,RSTART,RLENGTH)
 next
}
/port/{
 print ind,des,$2
}
'  Input_file

En caso de que sus cadenas puedan ser mayúsculas, minúsculas o mixtas, entonces puede agregar una sección BEGIN con IGNORECASE=1 en el código anterior y debería coincidir con las cadenas en cualquier caso.

Explicación: Lo siguiente es solo para fines explicativos, consulte el código completo arriba, por favor.

-v OFS="," establece el separador de campo de salida como una coma para todas las líneas.

gsub(/\r/,"") sustituye globalmente \ r caracteres de control m con NULL según el comentario de OP que estaban allí.

sub(/^ +/,"") Sustituyendo aquí el espacio inicial de línea con NULL.

La línea de búsqueda /lag/{Ind=$2;next} que tenía un retraso de cadena y creaba una variable Ind cuyo valor es $ 2 a continuación omitirá todas las declaraciones adicionales de aquí en adelante.

/description...../ busca la línea que tiene una descripción de cadena y luego usa la función de coincidencia de awk para buscar expresiones regulares desde " hasta " en la misma línea. Al guardar este valor de expresión regular coincidente en la variable denominada desc, a continuación se omitirán todas las declaraciones adicionales desde aquí.

/port/... busca la línea que tiene el puerto de cadena y luego imprime el valor de ind, des, $ 2 aquí según el requisito de OP.

1
RavinderSingh13 3 oct. 2019 a las 15:32

Otro awk:

awk '$1~/lag/{l=$2;next}
     $1~/description/{d=substr($0,index($0,"\""));next}
     $1~/port/{print l,d,$2}
' OFS=, file

Las 2 primeras declaraciones obtienen el segundo campo en las variables l y d respectivamente para las palabras clave lag y description.

La última declaración imprime las 2 variables y el segundo campo asociado a la palabra clave port.

0
oliv 2 oct. 2019 a las 15:00
$ cat tst.awk
BEGIN { OFS="," }
{
    tag = $1
    sub(/^[[:space:]]*[^[:space:]]+[[:space:]]*/,"")
    vals[++numVals] = $0
}
tag == "exit" {
    for (valNr=3; valNr<numVals; valNr++) {
        print vals[1], vals[2], vals[valNr]
    }
    numVals = 0
}

$ awk -f tst.awk file
1,"LAG-1 GOES TO LAG-2",1/2/1
1,"LAG-1 GOES TO LAG-2",1/2/2
1,"LAG-1 GOES TO LAG-2",3/2/3
10,"REMOVED-LAG-10-0.0.0.0",4/1/1
10,"REMOVED-LAG-10-0.0.0.0",5/1/1
11,"REMOVED-LAG-11-4.4.4.4",5/1/2
1
Ed Morton 2 oct. 2019 a las 16:16
58202817