
Necesito ordenar un archivo LDIF, donde varias líneas pertenecen a una principal.
Ejemplo
dn: 2
attr1: b
attr2: a
attr1: a
attr1: c
dn: 3
attr2: a
attr1: c
attr1: b
attr1: a
dn: 1
attr1: a
attr1: c
attr1: b
attr2: a
a este
dn: 1
attr1: a
attr1: b
attr1: c
attr2: a
dn: 2
attr1: a
attr1: b
attr1: c
attr2: a
dn: 3
attr1: a
attr1: b
attr1: c
attr2: a
Entonces, todas las líneas principales que comienzan con dn están ordenadas, debajo todos los attrx están ordenados y si attrx tiene múltiples valores, también están ordenados. He hecho esto con la línea de lectura, pero esto lleva horas en archivos grandes. ¿Existe una forma más rápida de hacer lo mismo con los comandos bash?
El valor de un atributo siempre ocupa solo una línea. Si hay varios valores, cada uno toma una línea. Ninguna línea está codificada en base64.
Respuesta1
usando su archivo de ejemplo
awk 'BEGIN {RS="\n\n\n";FS="\n\n";OFS="*";ORS=""} {print $1,$2,$3,$4,$5}' file |awk -F'*' '{for(i=1; i<=NF; i++) c[i]=$i; n=asort(c); for (i=1; i<=n; i++) printf "%s%s*", c[i], (i<n?OFS:RS); delete c}' |sed 's/^*//' |awk -F'*' '{print $5"*"$1"*"$2"*"$3"*"$4}' |sort |awk -F'*' 'BEGIN{OFS="\n\n";ORS="\n\n\n"} {print $1,$2,$3,$4,$5;}'
Convierta cada bloque de texto en filas y use '*' para separar los campos
awk 'BEGIN {RS="\n\n\n";FS="\n\n";OFS="*";ORS=""} {print $1,$2,$3,$4,$5}' file dn: 2*attr1: b*attr2: a*attr1: a*attr1: c dn: 3*attr2: a*attr1: c*attr1: b*attr1: a dn: 1*attr1: a*attr1: c*attr1: b*attr2: a
Ordene los campos dentro de las líneas y use '*' para separar los campos
awk 'BEGIN {RS="\n\n\n";FS="\n\n";OFS="*";ORS=""} {print $1,$2,$3,$4,$5}' file |awk -F'*' '{for(i=1; i<=NF; i++) c[i]=$i; n=asort(c); for (i=1; i<=n; i++) printf "%s%s*", c[i], (i<n?OFS:RS); delete c}' |sed 's/^*//'
attr1: a *attr1: b *attr1: c *attr2: a *dn: 2 attr1: a *attr1: b *attr1: c *attr2: a *dn: 3 attr1: a *attr1: b *attr1: c *attr2: a *dn: 1
reorganice los campos en las líneas para 'imprimir dn: x' en primer lugar
awk 'BEGIN {RS="\n\n\n";FS="\n\n";OFS="*";ORS=""} {print $1,$2,$3,$4,$5}' file |awk -F'*' '{for(i=1; i<=NF; i++) c[i]=$i; n=asort(c); for (i=1; i<=n; i++) printf "%s%s*", c[i], (i<n?OFS:RS); delete c}' |sed 's/^*//' |awk -F'*' '{print $5"*"$1"*"$2"*"$3"*"$4}'
dn: 2*attr1: a *attr1: b *attr1: c *attr2: a dn: 3*attr1: a *attr1: b *attr1: c *attr2: a dn: 1*attr1: a *attr1: b *attr1: c *attr2: a
Ordenar las líneas por la primera columna o campo
awk 'BEGIN {RS="\n\n\n";FS="\n\n";OFS="*";ORS=""} {print $1,$2,$3,$4,$5}' file |awk -F'*' '{for(i=1; i<=NF; i++) c[i]=$i; n=asort(c); for (i=1; i<=n; i++) printf "%s%s*", c[i], (i<n?OFS:RS); delete c}' |sed 's/^*//' |awk -F'*' '{print $5"*"$1"*"$2"*"$3"*"$4}' |sort
dn: 1*attr1: a *attr1: b *attr1: c *attr2: a dn: 2*attr1: a *attr1: b *attr1: c *attr2: a dn: 3*attr1: a *attr1: b *attr1: c *attr2: a
Convertir las filas a una columna e insertar líneas vacías
awk 'BEGIN {RS="\n\n\n";FS="\n\n";OFS="*";ORS=""} {print $1,$2,$3,$4,$5}' file |awk -F'*' '{for(i=1; i<=NF; i++) c[i]=$i; n=asort(c); for (i=1; i<=n; i++) printf "%s%s*", c[i], (i<n?OFS:RS); delete c}' |sed 's/^*//' |awk -F'*' '{print $5"*"$1"*"$2"*"$3"*"$4}' |sort |awk -F'*' 'BEGIN{OFS="\n\n";ORS="\n\n\n"} {print $1,$2,$3,$4,$5;}'
dn: 1
attr1: a
attr1: b
attr1: c
attr2: a
dn: 2
attr1: a
attr1: b
attr1: c
attr2: a
dn: 3
attr1: a
attr1: b
attr1: c
attr2: a
Sé que estoy usando demasiados pasos.