Сортировка структурированного файла с помощью команд bash

Сортировка структурированного файла с помощью команд bash

Мне нужно отсортировать LDIF-файл, в котором несколько строк принадлежат родительскому файлу.

Пример

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

к этому

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

Итак, все родительские строки, начинающиеся с dn, сортируются, ниже сортируются все attrx, и если attrx имеет несколько значений, они также сортируются. Я сделал это с помощью read line, но это занимает часы на больших файлах. Есть ли более быстрый способ сделать то же самое с помощью команд bash?

Значение атрибута всегда занимает только одну строку. Если есть несколько значений, каждое занимает одну строку.Ни одна строка не закодирована в base64.

решение1

используя ваш файл-пример

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;}'

Преобразуйте каждый блок текста в строки и используйте «*» для разделения полей.

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

Сортируйте поля в строках, используя «*» для разделения полей.

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

переставьте поля в строках так, чтобы «print dn: x» был на первом месте

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

Сортировка строк по первому столбцу или полю

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

Преобразование строк в один столбец и вставка пустых строк

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

Я знаю, что использую слишком много шагов.

Связанный контент