awk - таблица различных значений - PullRequest
0 голосов
/ 26 декабря 2011

С этим "|"файл с разделителями: dummy.dat

sid|storeNo|latitude|longitude
2|1|-28.03720000
9|2
10
jgn352|1|-28.03720000
9|2|fdjkjhn422-405
0000543210|gfdjk39

Например, значение «-28.03720000» в поле широты появляется дважды, затем в выходных данных оно будет появляться один раз, но иметь его в конце (2).В другом примере значение «2» появилось один раз в поле sid, но дважды в поле storeno - поэтому для вывода у него будет одна запись в поле sid (с «(1)» в конце) и одна запись в поле storenoполе (с "(2)" в конце).

Желаемый результат:

sid|storeNo|latitude|longitude
9(2)|1(2)|-28.03720000(2)
0000543210(1)|2(2)|fdjkjhn422-405(1)
10(1)|gfdjk39(1)    
2(1)
jgn352(1)

Другой пример приемлемого желаемого результата (для того же входного файла):

sid|storeNo|latitude|longitude
9(2)|2(2)|-28.03720000(2)
jgn352(1)|1(2)|fdjkjhn422-405(1)
10(1)|gfdjk39(1)    
0000543210(1)
2(1)

Каково общее решение для производства такой продукции, как указано выше?Я открыт для awk, bash, perl.etc. Это отдельные значения каждого поля (со счетчиком вхождений этого значения в "()" и затем упорядоченным desc по количеству вхождений):

Нашли эти 2 фрагмента кода, которые дают общее представление, но только в другом формате вывода:

Script 1:
awk -F"|" ' {
                for( i = 1; i <= NF; i++ )
                {
                        count[i " " $(i)]++;    # count by field number and field value
                        uniq[$(i)] = 1;         # save a list of unique strings
                }
                if( NF > fields )
                        fields = NF;            # in case a variable number in file; capture max
        }
        END {
                for( i = 1; i <= fields; i++ )
                {
                        printf( "field %d\n", i );
                        for( x in uniq )
                                if( count[i " " x] )
                                        printf( "%s (%d)\n", x, count[i " " x] );  # print by field and value
                        printf( "\n" );
                }
        } ' dummy.dat

Script 2:
awk -F"|" '{for (i=1;i<=NF;i++) a[i FS $i]++} END {for (i in a) print i,"(",a[i],")" |"sort -n" } ' dummy.dat

1 Ответ

2 голосов
/ 26 декабря 2011
awk -F'|' '

FNR==NR{
  if(FNR>1)
    for(i=1;i<=NF;i++)
      a[$i,i]++
  next
}
FNR==1{print}
FNR>1{
  for(j=1;j<=NF;j++)
    if(b[$j,j]++)
      printf("|")
    else
      printf("%s(%s)|",$j,a[$j,j])
  print ""
}' ./dummy.dat ./dummy.dat | sed 's/|*$//'

выход

sid|storeNo|latitude|longitude
2(1)|1(2)|-28.03720000(2)
9(2)|2(2)
10(1)
jgn352(1)
||fdjkjhn422-405(1)
0000543210(1)|gfdjk39(1)

Примечание: Чтобы избавиться от трейлинга | потребуется дополнительная работа. Надеюсь, этого будет достаточно.
Я только что передал окончательный результат на sed 's/|*$//'

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