Сохранение строк повторяется определенное количество раз

У меня есть файл с несколькими столбцами и определены строки, где значения в столбце 3 были дублированы.

Пример ввода:

ABC 1 2 APPLE 3 4 PEAR 9 3 LEMON 8 3 ORANGE 8 2 APPLE 3 4 APPLE 9 3 LEMON 8 3 PEAR 

Я могу подсчитать, как часто повторяется слово в столбце 3, используя:

 awk '{print $3}' [input filename] | sort | uniq -c > [output filename] 

Вывод:

 3 APPLE 2 PEAR 2 LEMON 1 ORANGE 

Я бы хотел, чтобы строки повторялись 3 раза:

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

 APPLE 

или

 1 2 APPLE 8 2 APPLE 3 4 APPLE 

Я не возражаю, если все столбцы печатаются из исходного входного файла или только значения третьего столбца.

Используя sort -u выдает любую строку, которая появилась хотя бы один раз, и это не то, что мне нужно.

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

 $ awk 'NR==FNR{a[$3]++; next} a[$3]==3' ip.txt ip.txt 1 2 APPLE 8 2 APPLE 3 4 APPLE $ awk 'NR==FNR{a[$3]++; next} a[$3]==2' ip.txt ip.txt 3 4 PEAR 9 3 LEMON 9 3 LEMON 8 3 PEAR $ awk 'NR==FNR{a[$3]++; next} a[$3]<2' ip.txt ip.txt ABC 8 3 ORANGE 

Решение awk :

– выводить только записи, которые происходят не менее 3 раз:

 awk '++a[$3]==3{ print $3 }' file 
  • ++a[$3] – последовательно увеличивающееся количество уникальных значений 3-го поля

– выводить только записи, которые происходят ровно в 3 раза:

 awk '{++a[$3]}END{ for(i in a) if(a[i]==3) print i }' file 

Выход:

 APPLE 

Передайте вывод вашего конвейера через awk '$1 == 3 { print $2 }' чтобы получить только APPLE .

В качестве альтернативы, счетчик с awk с самого начала:

 awk '{ c[$3]++; r[$3] = r[$3] ? r[$3] ORS $0 : $0 } END { for (i in c) { if (c[i] == 3) print r[i] } }' file 1 2 APPLE 8 2 APPLE 3 4 APPLE 

Сценарий awk будет подсчитывать в c , сколько раз значения в столбце 3 происходят. Каждая строка ввода добавляется к r которая является ассоциативным массивом, например c , с ключом в третьем столбце.

В конце выводятся только строки, третий столбец которых происходит ровно три раза.

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

 awk '{print $3}' yourInputFile | sort | uniq -c | while read -r line do echo $line | [ `awk '{print $1}'` -gt 2 ] && echo $line | awk '{print $2}' done 

И если вы хотите ограничить отображение строк, которые имеют количество вхождений, строго равное 3 , это еще проще. grep может использоваться как @wvxvw предлагаемый в комментариях. Вам даже не нужно перебирать в этом случае, но вам нужно экранировать grep чтобы не получать значения, начинающиеся с 3, но которые больше, например 30:

 awk '{print $3}' yourInputFile | sort | uniq -c | grep '^\s*3\s' | awk '{print $2}' 

В обоих случаях вывод:

 APPLE