Необходимо отфильтровать данные на основе двух столбцов, имеющих много отношений, используя awk

У меня большой файл с 50-ю столбцами и 100K строк, разделенных символом |. Теперь $ 2 (col 2) имеет несколько типов значений $ 1 (col 1), что означает, что col 2 будет повторяться. Поэтому я отсортировал файл. Теперь мне нужно извлечь / отфильтровать файл результатов на основе нижеследующего условия: $ 1 – столбец 1 $ 2 – столбец 2

существует от одного до нескольких отношений корабль между $ 2 и $ 1

условие 1: когда $ 2 имеет оба типа $ 1 (значение $ 1 для $ 2 составляет более 8000, а также менее 8000), затем выберите полную строку, где $ 1 <8000 для данного $ 2 (столбец 2)

условие 2: если $ 2 имеет только $ 1> = 8000, тогда выберите полную строку, где $ 1 является наименьшим для данного $ 2 (столбец 2). Например: исходный файл. В приведенном ниже примере мы имеем 3 типа $ 2 (1234,123 и 456) Теперь 1234 имеет 3 типа значения в столбце 1 ($ 1), значит, больше, а также меньше 8000. Таким образом, мы выбрали полную строку для тех, у кого есть $ 1 <8000.

Для 123 и 465 мы имеем значение столбца 1, превышающее 8000 ($ 1> 80000), поэтому мы выбрали последнюю строку (на основе более высокого значения столбца 8).

Файл примера

4000|1234||||||23 5000|1234||||||40 9000|1234||||||25 10000|123|||||||21 9000|123|||||||22 22000|456|||||||27 15000|456|||||||29 

файл результатов будет иметь:

 4000|1234||||||23 5000|1234||||||40 9000|123|||||||22 15000|456|||||||29 

Пожалуйста посоветуй. Заранее спасибо.

  • Как можно выполнить команду с неизвестным числом аргументов в оболочке POSIX?
  • Параллельный для долгого фильтра
  • Копирование последнего измененного файла из нескольких каталогов
  • Извлечение каталога из stdout из wget
  • Преобразование цикла кода в функцию
  • Перенаправление stdout в терминал и файл без использования канала?
  • grep переменной оболочки не находит ничего
  • sed повторяет последнюю строку в потоке
  • 9 Solutions collect form web for “Необходимо отфильтровать данные на основе двух столбцов, имеющих много отношений, используя awk”

    попробуйте (u, являющийся вашим файлом)

     sort -n -t\| -k2 -k1 < u | awk -F\| '$1 < 8000 { a[$2]++ ; print } $1 >= 8000 { if ( !a[$2] && ( !e[$2] || e[$2]<$8 )) {u[$2]=$0;e[$2]=$8;} ; } END { for ( i in u ) print u[i] ;}' 

    дает

     4000|1234

    23 5000|1234

    40 15000|456

    29 9000|123

    22

    где

    • -t\| и -F\| указать sort и awk для использования | как разделитель
    • -k1 : сортировать по второму, затем по полю
    • | в строке сортировки должен быть последний символ в строке
    • $1 < 8000 { a[$2]++ ; print } $1 < 8000 { a[$2]++ ; print } если значение менее 8000, напечатать строки и запомнить значение $ 2
    • $1 >= 8000 { ... } если выше, хранить наивысшую ценность
    • END { for ( i in u ) print u[i] ;} после выхода, сбросить все значение

    • вам может потребоваться повторная сортировка.

    • условие линии 2 может быть упрощено (если условие if нарушено {})

    • некоторые строки в вашем тесте имеют 9 полей.

    обратите внимание, что команда может быть одной выровненной

     ... | sort -n -t\| -k2 -k1 | awk -F\| '...' 
    Linux и Unix - лучшая ОС в мире.