Как вычислить сумму данных, которые имеют тот же идентификатор в первом столбце?

Полностью перечитанный ddrescue руководство и узнанный следующая опция:

-m file
--domain-logfile=file

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

Так вызов ddrescue выглядел бы примерно так:

# ddrescue -d -b 4096 -m sda1.log /dev/sda1 /mnt/sda1.img logfile2.log
2
07.01.2014, 12:32
4 ответа

Это GNU awk сценарий должен сделать задание:

$ awk 'NR==1 { size=NF;$1=$1;OFS="\t";print;next } 
{ for(i=2;i<=NF;i++) {id[$1]=$1; record[$1,i-1]+=$i} } 
END { PROCINFO["sorted_in"]="@ind_num_asc"
  for(i in id){ printf("%s\t",i);
    for(j=1;j<size;j++) printf("%s\t",record[i,j]);
    printf("\n");
  }
} ' data.txt > out.txt
$ cat out.txt
Id  a   b   c   d   e
1   6   9   12  15  18  
2   15  18  21  24  27  
3   34  38  42  46  50  
4   23  25  27  29  31  
5   27  29  31  33  35

Править:

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

$ awk 'NR==1 { size=NF;$1=$1;OFS="\t";print;next }
{ if(o[$1]==0) o[$1]=NR
  for(i=2;i<=NF;i++) {record[$1,i-1]+=$i} }
END { PROCINFO["sorted_in"]="@val_num_asc"
  for(i in o){ printf("%s\t",i)
    for(j=1;j<size;j++) printf("%s\t",record[i,j])
    printf("\n") }
}'
3
27.01.2020, 21:54
  • 1
    Хороший один, +1. Что PROCINFO для? Вы, кажется, не используете его. Это должно отсортировать идентификаторы? Что, если они не являются числовыми как в простом примере в OP? –  terdon♦ 03.01.2014, 14:06
  • 2
    @terdon PROCINFO должен действительно здесь отсортировать Ids. Нет никакой конкретной проблемы, некоторые, или все они не являются числовыми, они будут просто отсортированы в алфавитном порядке. –  jlliagre 03.01.2014, 14:15
  • 3
    @terdon порядок не сохраняется с Вашим awk решение. –  jlliagre 03.01.2014, 14:21
  • 4
    Нет это не (мое плохое), хотя они действительно выходят отсортированные на моей системе по некоторым причинам, независимо от того, каким порядком они найдены во входном файле. –  terdon♦ 03.01.2014, 14:23
awk '
    NR==1 {print; n=NF; next} 
    {
        id[$1]=1
        for (i=2; i<=n; i++) 
            sum[$1,i] += $i
    } 
    END {
        m = asorti(id, id_s);   # sort the ids
        for (i=1; i<=m; i++) {
            printf "%d", id_s[i]
            for (j=2; j<=n; j++)
                printf " %d", sum[id_s[i],j]
            print ""
        }
    }
' data.txt | column -t > out.txt

out.txt теперь содержит

Id  a   b   c   d   e
1   6   9   12  15  18
2   15  18  21  24  27
3   34  38  42  46  50
4   23  25  27  29  31
5   27  29  31  33  35
1
27.01.2020, 21:54

Perl путь:

$ perl -ane '
    if($.==1){s/\s+/\t/g; print "$_\n"; @a=@F; shift(@a); }
    else{
         push @vals,$F[0] unless defined($sum{$F[0]});
         for($i=0; $i<=$#a;$i++){
           $sum{$F[0]}{$a[$i]}+=$F[$i+1]; 
         }
    }
    END{
     for $f (@vals){ 
      print "$f\t"; 
      print "$sum{$f}{$_}\t" for @a; 
      print "\n" 
     }
    } ' file 

awk путь:

$ awk 'BEGIN{OFS="\t"}
       (NR==1){
         printf "%s%s",$1,OFS; 
         for(i=2;i<=NF;i++){ k[i]=$(i); printf "%s%s",$(i),OFS;} 
         printf "\n"; next;
       }{for(i=2;i<=NF;i++){s[$1][k[i]]+=$(i); names[$1]++;}}
       END{for(i in names){
           printf "%s%s",i,OFS; 
           for(l in s[i]){printf "%s%s", s[i][l],OFS;}
           printf "\n";}
       }' file

Оба из них изменят пробелы на вкладки для хранения столбцов выровненными. Их вывод:

Id  a   b   c   d   e   
1   6   9   12  15  18  
2   15  18  21  24  27  
3   34  38  42  46  50  
4   23  25  27  29  31  
5   27  29  31  33  35  
1
27.01.2020, 21:54
  • 1
    я не боюсь ни один из этих сценариев, генерирует ожидаемый вывод. –  jlliagre 03.01.2014, 13:54
  • 2
    @jlliagre да, была ошибка в Perl один, должен работать теперь. awk каждый хорошо работает здесь, оба дают тот же вывод как Ваш (единственная разница, являющаяся той шахтой, добавляет, что запаздывающая вкладка к 1-й строке также, в то время как Ваш только добавляет его к другим). –  terdon♦ 03.01.2014, 14:05
  • 3
    +1 версия жемчуга теперь хорошо работает, и поддержите исходный идентификационный порядок. awk версия все еще произвела случайным образом заказанные строки для меня. –  jlliagre 03.01.2014, 14:19
  • 4
    @jlliagre действительно? Случайный заказанный? Странный, они выходят отсортированные на моей системе (даже если я изменяю порядок в исходном файле, который сбивает с толку). Я использую GNU Awk 4.1.0. –  terdon♦ 03.01.2014, 14:22
  • 5
    я использую GNU Awk 4.0.1, они, возможно, изменили поведение по умолчанию, хотя 4,1 документации все еще указывает: As a side note, sorting the array indices before traversing the array has been reported to add 15% to 20% overhead to the execution time of awk programs. For this reason, sorted array traversal is not the default. –  jlliagre 03.01.2014, 14:54

С gnu datamash :

{ head -n 1; datamash -s -g 1 sum 2 sum 3 sum 4 sum 5 sum 6; } <infile

используйте -W , если поля разделены более чем одним пробелом:

{ head -n 1; datamash -Wsg 1 sum 2 sum 3 sum 4 sum 5 sum 6; } <infile
1
27.01.2020, 21:54

Теги

Похожие вопросы