2015-11-24 3 views
0

Это довольно просто, может быть, но я укладываю. Спасибо за любую помощь. У меня есть входной файл с двумя двумя столбцами. В одном столбце у меня есть идентификатор, а во втором - значение, связанное с ним. Мне нужен вывод, где первый столбец будет ID (повторений не допускается), а во втором столбце печатается среднее. Иды не всегда повторяются, и если они повторяются, это может быть только последовательно и с максимальным значением повторения два.awk сравнить последовательные строки

Входной

10;10 
10;20 
20;30 
20;40 
30;15 
40;10 
40;12 

Желаемая выход

10;15 
20;35 
30;15 
40;11 
+0

Любое количество вопросов, на этом сайте, достаточно похожи на это, что вы должны быть в состоянии понять его из них. –

+0

Прошу прощения, я проверил некоторые из них, но все еще смущен ... любая вспомогательная помощь, пожалуйста? – user3666956

ответ

0

(написано в прямом эфире, я не пробовал, предположим GNU AWK, предположим, отсортированный ввод)

awk -F';' ' 
    BEGIN { 
     id="" 
    } 
    $1 != id { 
     if (id != "") { 
      printf("%s;%d\n", id, sum/n); 
      n = sum = 0; 
      id = str($1); 
     } 
     sum += $2; 
     n++; 
    } 
    END { 
     if (n > 0) printf("%s;%s\n", id, sum/n); 
    } 
' 
+0

В этом нет ничего особенного в gawk, но выполнение выше приведет к синтаксической ошибке из-за попытки использовать одинарные кавычки внутри одного сценария с разделителями кавычек, а в awk нет функции с именем 'str()', и вам не нужно ложные конечные полуколоны, а printf - встроенная функция, а не функция, поэтому parens вокруг args printf не делают то, что вы, вероятно, думаете. Как только это будет исправлено, он также потерпит неудачу с делением на нулевую ошибку, если будет запущен пустой файл. –

+0

@ EdMorton Я могу жить с этим. Я написал это напрямую, а не тестировался, как предупреждал. Обратите внимание, что ОП не пробовал ничего, прежде чем спрашивать. Я исправил самые очевидные ошибки; не знал о printf, я всегда использую его таким образом, и он просто работает. – cadrian

4

Это один-лайнер делает это:

awk -F';' -v OFS=";" '{a[$1]+=$2+0;b[$1]++}END{for(x in a)print x,a[x]/b[x]}' file 

тест с вашими данными:

kent$ cat f 
10;10 
10;20 
20;30 
20;40 
30;15 
40;10 
40;12 

kent$ awk -F';' -v OFS=";" '{a[$1]+=$2+0;b[$1]++}END{for(x in a)print x,a[x]/b[x]}' f 
10;15 
20;35 
30;15 
40;11 
+1

@fedorqui true, у меня был 'OFS', я удалился, потому что у меня есть' printf' в любом случае, 'OFS' делает' printf' дольше .. :-) – Kent

+1

@fedorqui вы правы .... !! Я забыл, что 'a/b' будет int ..... urh ... Я обновляю его – Kent

+0

Спасибо большое! Но что, если у меня действительно есть другие столбцы во входном файле, я также хочу напечатать среднее значение? Я подумал, что мне будет легко добавить это в свой скрипт, но я действительно не знаю, как ... Фактический входной файл содержит 80 столбцов, действующих как второй, о котором я упомянул ... – user3666956

3
$ cat tst.awk 
BEGIN { FS=OFS=";" } 
($1 != prev) && (NR>1) { print prev, sum/cnt; sum=cnt=0 } 
{ prev=$1; sum+=$2; cnt++ } 
END { if (cnt) print prev, sum/cnt } 

$ awk -f tst.awk file 
10;15 
20;35 
30;15 
40;11 
+0

Большое спасибо! Но что, если у меня действительно есть другие столбцы во входном файле, я также хочу напечатать среднее значение? Я подумал, что мне будет легко добавить это в свой скрипт, но я действительно не знаю, как ... Фактический входной файл содержит 80 столбцов, действующих как второй, который я упомянул – user3666956

+0

. Тогда вы должны действительно показать эти другие столбцы в образце вход/выход в ваш вопрос. Все, что вы хотите сделать, будет тривиально, но ваш комментарий может означать одну из нескольких вещей. И нет - не показывать 80 столбцов, 3 или 4 столбца будут работать нормально. –

+0

@ user3666956 некоторые советы - в программных решениях существует мир различий между 1 предметом и 2 пунктами, а также между 2 и 3 предметами. Существует также мир различий между последовательными и непоследовательными элементами. Поэтому, если вы публикуете вопрос THINK о том, как вы можете показать минимальный пример, который фиксирует вашу проблему, но если настоящая проблема связана с 3 или более пунктами, тогда не показывайте пример с 1 элементом (или даже двумя элементами) и надейтесь, что решение такая же, как для 3 или более. –