2-уровневая сортировка awk-массива

У меня есть этот входной файл ниже, где разделитель полей ir "+", который я хочу отсортировать на 2 уровня. Сначала по 3-му полю, а затем по 2-му полю в порядке возрастания.

Вход

240x151+140+624
240x151+462+176
240x151+87+257
240x151+366+355
240x151+77+448
240x151+468+542
178x59+223+65
178x59+417+65
178x59+611+65
178x59+29+65
110x16+255+63

Мой код, который у меня есть, ниже, но результат - не то, что мне нужно.

awk '{split($0,f,"+")
      a[$0]=f[3];
     }END{
          n=asorti(a,b)
          for (i=1;i<=n;i++) 
          print b[i]}' file.txt
110x16+255+63
178x59+223+65
178x59+29+65
178x59+417+65
178x59+611+65
240x151+140+624
240x151+366+355
240x151+462+176
240x151+468+542
240x151+77+448
240x151+87+257

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

110x16+255+63  
178x59+29+65   
178x59+223+65  
178x59+417+65  
178x59+611+65  
240x151+462+176
240x151+87+257 
240x151+366+355
240x151+77+448 
240x151+468+542
240x151+140+624

для этого в awk создайте новый ключ, объединив 3-е и 2-е поля и отсортируйте по этому ключу. Однако в этом нет необходимости, поскольку sort уже разработан для таких случаев.

karakfa 29.10.2018 20:24
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
36
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

sort - подходящий инструмент для этого

$ sort -t+ -k3n -k2,2n file

110x16+255+63
178x59+29+65
178x59+223+65
178x59+417+65
178x59+611+65
240x151+462+176
240x151+87+257
240x151+366+355
240x151+77+448
240x151+468+542
240x151+140+624

один из способов сделать это в awk, создав новый ключ, объединив 3-е и 2-е поля и отсортируя по этому ключу. Однако обратите внимание, что индексы массива будут отсортированы нечисловым образом. Итак, мы должны преобразовать их в текстовый отсортированный эквивалентный формат с нулевым заполнением. Предполагается, что наибольшее число состоит из 5 цифр (если не изменить соответственно).

$ awk -F+ '{k1=sprintf("%05d",$3); k2=sprintf("%05d",$2); a[k1,k2]=$0}
       END {n=asorti(a,d); for(i=1;i<=n;i++) print a[d[i]]}' file

110x16+255+63
178x59+29+65
178x59+223+65
178x59+417+65
178x59+611+65
240x151+462+176
240x151+87+257
240x151+366+355
240x151+77+448
240x151+468+542
240x151+140+624

Спасибо за Ваш ответ. Я закончил с сортировкой, но поскольку это часть другого скрипта, мне нужно дважды передать по конвейеру. Сначала чтение файла, затем конвейер для команды сортировки, а затем снова конвейер для awk для обработки результирующего вывода сортировки. Я хочу использовать для этого уникальную программу awk. Не могли бы вы показать мне, как было бы объединить поля 3 и 2 в качестве ключевых?

Ger Cas 29.10.2018 20:47

Как вы думаете, почему дополнительные трубопроводы - это проблема? awk изначально не имел функции sort.

karakfa 29.10.2018 21:01

Отличная каракфа, красивый, очень красивый трюк и комбинация с асорти (). Большое спасибо за помощь. Я 4 раза спрашивал, как это сделать, и в 4-й попытке вы получили решение.

Ger Cas 29.10.2018 22:21

Другой (не идеальный), использующий GNU awk и asorti()третий строковый аргумент для управления сравнением элементов массива:

awk '
{
    split($0,f,"+")
    a[$0]=f[3]                    # a["110x16+255+63"] = 63
}
END {
    OFS = ", "                      # for pretty output
    n=asorti(a,a,"@val_num_asc")  # NOTICE THE THIRD ARGUMENT, using asorti but "@val..."
    for (i=1;i<=n;i++)            # "@ind..." would sort using the index
        print i,a[i]              # I wrote a over old a but you could use b
}' file

Выход:

1, 110x16+255+63
2, 178x59+417+65
3, 178x59+611+65
4, 178x59+29+65
5, 178x59+223+65
6, 240x151+462+176
7, 240x151+87+257
8, 240x151+366+355
9, 240x151+77+448
10, 240x151+468+542
11, 240x151+140+624

При использовании "@ind_num_asc" порядок будет следующим:

1, 110x16+255+63
2, 178x59+223+65
3, 178x59+29+65
4, 178x59+417+65
5, 178x59+611+65
6, 240x151+140+624
7, 240x151+366+355
8, 240x151+462+176
9, 240x151+468+542
10, 240x151+77+448
11, 240x151+87+257

Привет, Джеймс. Превосходно. Еще более простое решение. Я понимаю, как на первом уровне сортируется 3-е поле, но я не вижу четко, как сортируется одинаково по возрастанию 2-го поля.

Ger Cas 30.10.2018 16:58

Я заговорил слишком рано. Кажется, ваше решение по-прежнему не выводит желаемый результат.

Ger Cas 30.10.2018 19:27

Другие вопросы по теме