С Schwartzian Transform
в Perl
, попробуйте следующее:
perl -e '
print map { $_->[0] }
sort { $b->[1] <=> $a->[1] }
map { [$_, length((split(/\|/))[1])] }
<>;
' input.txt
Вывод:
123|N1-G23-H40-K1-A11-C12-J12|banana|boy
123|N1-G23-H40-K1-A11-C12|banana|boy
123|F1-B23-G39-M22-Z12|some|girl
123|P1-G23-H40-K1|school|boy
123|E1-T23-N12|car|girl
123|V1-M12|car|girl
123|Z12|Goal|test
[Как это работает]
Чтобы понять алгоритм, будет удобно прочитать скрипт снизу вверх.
Первая функция:
map { [$_, length((split(/\|/))[1])] }
<>;
читает входной файл, затемгенерирует двумерный список, который содержит саму строку ввода в 1-м столбце и длину 2-го файла в 2-м столбце, например:
[["123|N1-G23-H40-K1-A11-C12-J12|banana|boy\n", 25],
["123|Z12|Goal|test\n", 3],
["123|F1-B23-G39-M22-Z12|some|girl\n", 13],
...]]
Вторая функция:
sort { $b->[1] <=> $a->[1] }
сортирует список по значениям во 2-х столбцах в порядке убывания, и результат будет выглядеть следующим образом:
[["123|N1-G23-H40-K1-A11-C12-J12|banana|boy\n", 25],
["123|N1-G23-H40-K1-A11-C12|banana|boy\n", 21],
["123|F1-B23-G39-M22-Z12|some|girl\n", 18],
...]]
Последняя функция:
print map { $_->[0] }
извлекает 1-е столбцы ивыводит результат.
Schwartzian transform
- полезный и эффективный метод (или идиома) для сортировки списка по определенному свойству элементов списка.