Группирование связанных строк данных в один столбец в Linux - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть CSV-файл, который генерируется ежедневно и автоматически, вывод которого похож на следующий пример:

"N","3.5",3,"Bob","10/29/17" 
"Y","4.5",5,"Bob","10/11/18" 
"Y","5",6,"Bob","10/28/18" 
"Y","3",1,"Jim", 
"N","4",2,"Jim","09/29/17" 
"N","2.5",4,"Joe","01/26/18"

Мне нужно преобразовать текст так, чтобы он был сгруппирован по человеку (четвертый столбец)и все записи в одной строке и в столбцах повторяются с использованием одной и той же последовательности: 1,2,3,5.В некоторых ячейках могут отсутствовать данные, но они должны оставаться в последовательности, поэтому столбцы выстраиваются в линию.Поэтому вывод, который мне нужен, будет выглядеть так:

"Bob","N","3.5",3,"10/29/17","Y","4.5",5,"10/11/18","Y","5",6,"10/28/18"
"Jim","Y","3",1,,"N","4",2,"09/29/17"
"Joe","N","2.5",4,"01/26/18"

Я открыт для использования sed, awk или почти любой стандартной команды Linux для выполнения этой задачи.Я пытался использовать awk, и хотя я близко, я не могу понять, как это закончить.

Вот команда, где я рядом.В нем перечислены заголовок и имена, но нет других данных:

awk -F"," 'NR==1; NR>1 {a[$4]=a[$4] ? i : ""} END {for (i in a) {print i}}' test2.csv

Ответы [ 3 ]

0 голосов
/ 08 ноября 2018

Не могли бы вы попробовать тоже, читая Input_file 2 раза, он будет выводить в той же последовательности, в которой 4-й столбец вошел в Input_file.

awk '
BEGIN{
  FS=OFS=","
}
FNR==NR{
  a[$4]=a[$4]?a[$4] OFS $1 OFS $2 OFS $3 OFS $5:$4 OFS $1 OFS $2 OFS $3 OFS $5
  next
}
a[$4]{
  print a[$4]
  delete a[$4]
}
'  Input_file  Input_file
0 голосов
/ 08 ноября 2018

Если есть вероятность того, что какое-либо из значений CSV будет иметь запятую, то для получения надежного, но простого решения будет целесообразно использовать инструмент, учитывающий CSV.

Один из подходов заключается в использовании одного из множества доступных инструментов командной строки csv2tsv. Разнообразие элегантных решений становится возможным. Например, можно передать CSV-файл в csv2tsv, awk и tsv2csv.

Вот еще одно решение, которое использует csv2tsv и :

csv2tsv < input.csv | jq -Rrn '
  [inputs | split("\t")]
  | group_by(.[3])[]
  | sort_by(.[2])
  | [.[0][3]] + ( map( del(.[3])) | add)
  | @csv
'

Это производит:

"Bob","N","3.5","3","10/29/17 ","Y","4.5","5","10/11/18 ","Y","5","6","10/28/18 "
"Jim","Y","3","1"," ","N","4","2","09/29/17 "
"Joe","N","2.5","4","01/26/18"

Обрезка лишних пробелов оставлена ​​в качестве упражнения: -)

0 голосов
/ 08 ноября 2018

вам нужно немного больше кода

$ awk 'BEGIN {FS=OFS=","} 
             {k=$4; $4=$5; NF--; a[k]=(k in a?a[k] FS $0:$0)} 
       END   {for(k in a) print k,a[k]}' file

"Bob","N","3.5",3,"10/29/17" ,"Y","4.5",5,"10/11/18" ,"Y","5",6,"10/28/18" 
"Jim","Y","3",1, ,"N","4",2,"09/29/17" 
"Joe","N","2.5",4,"01/26/18"

обратите внимание, что трюк NF-- может работать не во всех awk с.

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