Как использовать Sed или Perl для сортировки заданного текстового файла по номеру строки 2-го столбца по убыванию - PullRequest
0 голосов
/ 20 мая 2019

Как использовать Sed или Perl для сортировки заданного текстового файла по номеру строки 2-го столбца в порядке убывания

Input.txt

123|N1-G23-H40-K1-A11-C12-J12|banana|boy      
123|Z12|Goal|test     
123|F1-B23-G39-M22-Z12|some|girl     
123|E1-T23-N12|car|girl     
123|N1-G23-H40-K1-A11-C12|banana|boy     
123|V1-M12|car|girl     
123|P1-G23-H40-K1|school|boy

Output.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

Ответы [ 2 ]

0 голосов
/ 20 мая 2019

В одну сторону:

$ awk -F'|' -v OFS='|' '{ print $1, split($2, a, /-/), $2, $3, $4 }' input.txt |
    sort -t'|' -k 2nr,3 |
    cut -d'|' -f1,3,4,5
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

Бит awk добавляет новый второй столбец, который представляет собой число разделенных - слов в исходном втором столбце.sort затем сортирует эти выходные данные, сначала отсортировав этот новый второй столбец в обратном числовом порядке, и для каждой строки, в которой это число совпадает, сортирует третий столбец (исходную секунду) в возрастающем лексикографическом порядке.Наконец, cut удаляет этот дополнительный столбец.

0 голосов
/ 20 мая 2019

С 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 - полезный и эффективный метод (или идиома) для сортировки списка по определенному свойству элементов списка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...