Вход
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 идентификаторами, чтобы продемонстрировать проблему и дать нам что-то, с чем мы могли бы протестировать.





С вашими показанными образцами попробуйте следующее
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? Ценить это.
Я вижу, что часть {arr [$ 1] = (arr [$ 1]? Arr [$ 1] OFS: "") $ NF} проверяет, совпадает ли идентификатор следующей строки с текущей строкой, и если да? продолжайте добавлять последний столбец $ NF в этот массив для того же идентификатора. Это оно? Спасибо.
@ Process1, конечно, я добавил объяснение всего секунду назад, пожалуйста, проверьте его и дайте мне знать, если возникнут какие-либо вопросы. Для {arr[$1]=(arr[$1]?arr[$1] OFS:"")$NF} это похоже на использование тернарного оператора для добавления $ NF (последнее поле текущей строки), ? представляет собой размещение значения, если условие истинно, : представляет, если условие ложно, то помещает значение, которое идет после него. Условием является arr[$1], чтобы убедиться, что текущий элемент индекса (ключа) НЕ равен нулю, затем добавьте текущее последнее поле к значению arr [$ 1].
Спасибо, это помогает.
@ Process1, добро пожаловать, вы можете проголосовать за все полезные ответы и принять мой ответ, щелкнув галочку рядом с моим ответом, тоже приветствую и счастливого обучения :)
Да, конечно. Я пробовал awk самостоятельно. Где я могу найти подробное руководство по программированию на awk, которое охватывает такие темы, как условное добавление и манипуляции с массивами? Любая рекомендация. Спасибо
@ Process1, конечно, лично я узнал в основном по странице man awk, вы также можете сослаться на нее, помимо этого см. Книгу oreilly.com/library/view/effective-awk-programming/…, а math.utah.edu/docs/info/gawk_toc.html также может быть полезен для разучивания приветствий, вы можете попробовать учиться и где бы то ни было где-то застряли; вы также можете задать вопрос о переполнении стека :) ура
Спасибо, сделаю. Ценить это.
Вот еще один 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
Спасибо и за эту строчку.
Просто немного переработайте свой блок 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 для стабильной сортировки (-ов)
См .: Преобразование столбцов в строку с помощью awk