Порахуйте елементи в рядках з awk


2

У мене є текстовий файл з обмеженими вкладками, що містить такі дані

Col 1 Col 2
1     a
1     b
1     c
1     d
1     d
2     a
2     b
3     a

так далі і так далі.

Я хотів би перетворити цю структуру в

  a b c d
1 1 1 1 2
2 1 1 1 1
3 1 0 0 0

так що a, b, c і d стають стовпцями; 1, 2 і 3 стають одним рядком; а числа представляють кількість. Наприклад, 1 має один "a" і два "d" s.

Як це можна досягти, використовуючи awk або подібні інструменти?


Ласкаво просимо до Супер Користувача! Форматування тут безумовно може бути заплутаним, якщо ви новачок. Ознайомтеся з цим посібником . Цього разу я зафіксував це для вас. Удачі!
Попс

Відповіді:


0
awk 'NR>1 {
    count[$1,$2]++;
    rows[$1]++;
    cols[$2]++;
}
END {
    printf("%3s", "");
    for (col in cols) {
        printf("%4s", col);
    }
    printf("\n");
    for (row in rows) {
        printf("%3d", row);
        for (col in cols) {
            printf(" %3d", count[row,col]);
        }
        printf("\n");
    }
}' data

Це не обов'язково ефективно чи елегантно, але його слід читати досить легко і виконувати роботу. Крім того, рядки стовпців не обов'язково друкуються в упорядкованому порядку. Ключовим моментом є використання count[row,col]для імітації багатовимірного масиву, який безпосередньо не підтримується у awk. Пошук у Google за "багатовимірними масивами awk" відобразить кілька статей, включаючи цю .


0

Ось рішення PERL:

  perl -e '
    my (%col1, %col2); 
    while(<>){
        chomp; 
        @a=split(/\s+/); ## split line on whitespace
        $col2{$a[1]}++; ## Collect unique values from the 2nd column
        $col1{$a[0]}{$a[1]}++;## Count values per column/line
    } 
    my @l=sort keys %col2; 
    $"="\t"; ## Array record separator, using tabs to deal with variable size input
    print "\t@l\n"; 
    foreach my $c1 (sort keys(%col1)) {## For each column1 value
        print "$c1\t"; 
        my $str;
        for (my $i=0; $i<=$#l; $i++) {
        ## Collect the values for each position or 0 if there is none
        $col1{$c1}{$l[$i]}="0" unless defined($col1{$c1}{$l[$i]});
        $str.="$col1{$c1}{$l[$i]}\t";
        }
    chop($str); ## remove extra \t 
    print "$str\n";
    }' data   >ll
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.