Awk пытается распечатать каждый идентификатор и связанные элементы в новой строке массива

Вход

A1  +   1   2
A1  +   2   26
A1  +   3   7
A1  +   4   2
A1  +   5   1
A1  +   6   1
A1  +   7   0
A1  +   8   0
A1  +   9   3
A1  +   10  43

Ожидаемый результат

A1,2,26,7,2,1,1,0,0,3,43
awk -v OFS = "\t" '{a[$1][$3]=$NF;next} END {for (i in a) for (x=1;x<=10;x++) {printf "%s,",i,a[i][x]}; print ""}' <input> > <expected output>

Это просто дает мне одну строку со всеми значениями для всех идентификаторов, разделенных запятой. Я хочу напечатать каждый уникальный идентификатор (первый столбец) независимо в новой строке. Любая помощь приветствуется.

Поскольку ваши настоящие данные предположительно содержат более 1 идентификатора, вы должны опубликовать дату выборки с как минимум 2 идентификаторами, чтобы продемонстрировать проблему и дать нам что-то, с чем мы могли бы протестировать.

Ed Morton 09.04.2021 21:44
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
30
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

С вашими показанными образцами попробуйте следующее

awk '
BEGIN{
  OFS = ","
}
{
  arr[$1]=(arr[$1]?arr[$1] OFS:"")$NF
}
END{
  for(key in arr){
    print key,arr[key]
  }
}
' Input_file

Объяснение: Добавление подробного объяснения вышеизложенного.

awk '                     ##Starting awk program from here.
BEGIN{                    ##Starting BEGIN section from here.
  OFS = ","                 ##Setting OFS as comma here.
}
{
  arr[$1]=(arr[$1]?arr[$1] OFS:"")$NF  ##Creating array arr with index of $1 and keep adding its value here.
}
END{                      ##Starting END block of this program from here.
  for(key in arr){        ##Traversing through arr here.
    print key,arr[key]    ##Printing key and value here.
  }
}
' Input_file              ##Mentioning Input_file name here.

Спасибо, это работает. Пожалуйста, объясните, эта часть {arr [$ 1] = (arr [$ 1]? Arr [$ 1] OFS: "") $ NF}. что это делает, я с этим не знаком. Что, если я хочу напечатать A1, +, 2,26,7,2,1,1,0,0,3,43? Ценить это.

Process1 09.04.2021 20:38

Я вижу, что часть {arr [$ 1] = (arr [$ 1]? Arr [$ 1] OFS: "") $ NF} проверяет, совпадает ли идентификатор следующей строки с текущей строкой, и если да? продолжайте добавлять последний столбец $ NF в этот массив для того же идентификатора. Это оно? Спасибо.

Process1 09.04.2021 20:41

@ Process1, конечно, я добавил объяснение всего секунду назад, пожалуйста, проверьте его и дайте мне знать, если возникнут какие-либо вопросы. Для {arr[$1]=(arr[$1]?arr[$1] OFS:"")$NF} это похоже на использование тернарного оператора для добавления $ NF (последнее поле текущей строки), ? представляет собой размещение значения, если условие истинно, : представляет, если условие ложно, то помещает значение, которое идет после него. Условием является arr[$1], чтобы убедиться, что текущий элемент индекса (ключа) НЕ равен нулю, затем добавьте текущее последнее поле к значению arr [$ 1].

RavinderSingh13 09.04.2021 20:41

Спасибо, это помогает.

Process1 09.04.2021 20:44

@ Process1, добро пожаловать, вы можете проголосовать за все полезные ответы и принять мой ответ, щелкнув галочку рядом с моим ответом, тоже приветствую и счастливого обучения :)

RavinderSingh13 09.04.2021 20:45

Да, конечно. Я пробовал awk самостоятельно. Где я могу найти подробное руководство по программированию на awk, которое охватывает такие темы, как условное добавление и манипуляции с массивами? Любая рекомендация. Спасибо

Process1 09.04.2021 20:48

@ Process1, конечно, лично я узнал в основном по странице man awk, вы также можете сослаться на нее, помимо этого см. Книгу oreilly.com/library/view/effective-awk-programming/…, а math.utah.edu/docs/info/gawk_toc.html также может быть полезен для разучивания приветствий, вы можете попробовать учиться и где бы то ни было где-то застряли; вы также можете задать вопрос о переполнении стека :) ура

RavinderSingh13 09.04.2021 20:51

Спасибо, сделаю. Ценить это.

Process1 09.04.2021 20:57

Вот еще один awk, который немного короче:

awk -v OFS=, '{a[$1] = a[$1] OFS $4} END {for (i in a) print i a[i]}' file

A1,2,26,7,2,1,1,0,0,3,43

Спасибо и за эту строчку.

Process1 09.04.2021 20:44

Просто немного переработайте свой блок END

  END {
      for (i in a) {
          printf "%s", i
          for (x=1; x<=10; x++) printf ",%s", a[i][x]
          print ""
      }
  }
A1,2,26,7,2,1,1,0,0,3,43

Чтобы сохранить порядок идентификаторов на входе и не считывать все данные в память:

$ awk '
    $1!=prev { if (NR>1) print prev vals; prev=$1; vals = "" }
    { vals=vals "," $4 }
    END { print prev vals }
' file
A1,2,26,7,2,1,1,0,0,3,43

Если ваш ввод не сгруппирован по идентификатору, выполните sort -k1,1 -s file | awk '...', используя сортировку GNU для стабильной сортировки (-ов)

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