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 имеет один "а" и два "д".

Как это можно сделать с помощью awk или аналогичных инструментов?

2 ответа2

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .