Процесс подсчета и сопоставления - PullRequest
0 голосов
/ 10 августа 2011

У меня проблема с awk: (

)

Я буду считать первые элементы столбца в main.file, и если его значение больше 2, я напечатаю первый и второй столбцы.

main.file

1725009 7211378
3353866 11601802
3353866 8719104
724973 3353866
3353866 7211378

Например, число «3353866» в первом столбце равно 3, поэтому output.file будет выглядеть так:

output.file

3353866 11601802
3353866 8719104
3353866 7211378

Как я могу сделать это в awk?

Ответы [ 6 ]

1 голос
/ 10 августа 2011

Другой подход - дважды запустить файл: он немного медленнее, но код очень аккуратный:

awk '
  NR==FNR {count[$1]++; next}
  count[$1] > 2 {print}
' main.file main.file
1 голос
/ 10 августа 2011

Если вы имеете в виду элементы как минимум с 3 вхождениями, вы можете собирать вхождения в одном массиве, а собранные значения в виде предварительно отформатированной или разделенной строки в другом.Порядок вывода будет по существу случайным;вам понадобится другая переменная для отслеживания номеров строк, если вы хотите, чтобы порядок был стабильным.

Это будет несколько менее хакерским в Perl или Python, где хеш / dict может содержать структурированное значение, напримеркак список.

0 голосов
/ 10 августа 2011

в зависимости от того, как выглядит вопрос и редактирование Ray Toal, я предполагаю, что вы имеете в виду, основываясь на подсчете, поэтому что-то вроде этого работает:

awk '!y[$1] {y[$1] = 1} x[$1] {if(y[$1]==1) {y[$1]==2; print $1, x[$1]}; print} {x[$1] = $2}'
0 голосов
/ 10 августа 2011

Сначала выполните сортировку, а затем используйте awk для печати, только если у вас есть 3 или более раз в 1-м поле:

cat your_file | sort -n | awk 'prev == $1 {count++; p0=p1; p1=p2; p2=$2}
prev != $1 {prev=$1; count=1; p2=$2}
count == 3 {print $1 " " p0; print $1 " " p1; print $1 " " p2}
count > 3 {print $1 " " $2}'

Это позволит избежать использования awk слишком большого объема памяти в случае большого входного файла.

0 голосов
/ 10 августа 2011

Один из подходов состоит в том, чтобы отслеживать все просмотренные записи, соответствующий ключ $1 для каждой записи и частоту появления каждого ключа. После того, как вы записали их для всех строк, вы можете выполнять итерацию по всем сохраненным записям, печатая только те, для которых количество ключей больше двух.

awk '{ 
    record[NR] = $0; 
    key[$0] = $1; 
    count[$1]++ 
} 

END { 
    for (n=1; n <= length(record); n++) { 
        if (count[key[record[n]]] > 2) { 
            print record[n] 
        }
    } 
}'
0 голосов
/ 10 августа 2011
awk '{store[$1"-"lines[$1]] = $0; lines[$1]++;}
  END {for (l in store) {
    split(l, pair, "-"); if (lines[pair[1]] > 2) { print store[l] } } }'
...