Удалить всю строку в файле, если первый столбец повторяется

Удалить всю строку в файле, если первый столбец повторяется

У меня есть файл, содержащий два столбца и 10 миллионов строк. Первый столбец содержит много повторяющихся значений, но в столбце 2 есть отдельное значение. Я хочу удалить повторяющиеся строки и оставить только одну, используя awk. Примечание: файл отсортирован по значениям в столбце 1. Например:

1.123 -4.0
2.234 -3.5
2.234 -3.1
2.234 -2.0
4.432 0.0
5.123 +0.2
8.654 +0.5
8.654 +0.8
8.654 +0.9
.
.
.
.

Ожидаемый результат

1.123 -4.0
2.234 -3.5
4.432 0.0
5.123 +0.2
8.654 +0.5
.
.
.
.

решение1

Несколько способов:

  1. awk

    awk '!a[$1]++' file
    

    Вот очень сжатый способ записи этого:

    awk '{if(! a[$1]){print; a[$1]++}}' file
    

    Итак, если текущего первого поля ( $1) нет в aмассиве, вывести строку и добавить 1-е поле к a. В следующий раз, когда мы увидим это поле, оно будет в массиве и поэтому не будет выведено.

  2. Перл

    perl -ane '$k{$F[0]}++ or print' file
    

    или

    perl -ane 'print if !$k{$F[0]}++' file
    

    Это в основном то же самое, что и awkодин. -nзаставляет perl читать входной файл построчно и применять скрипт, предоставленный к -eкаждой строке. -aавтоматически разобьет каждую строку по пробелам и сохранит полученные поля в @Fмассиве. Наконец, первое поле добавляется в %kхэш, и если его там еще нет, строка выводится. То же самое можно записать как

    perl -e 'while(<>){
                @F=split(/\s+/); 
                print unless defined($k{$F[0]}); 
                $k{$F[0]}++;
             }' file
    
  3. Coreutils

    rev file | uniq -f 1 | rev
    

    Этот метод работает, сначала переворачивая строки так, fileчто если строка 12 345, то теперь она будет 543 21. Затем мы используем , uniq -f 1чтобы игнорировать первое поле, то есть столбец, в котором находится 543. Есть поля внутри file. Использование uniqздесь имеет эффект фильтрации любых дубликатов строк, оставляя только по одной из каждой. Наконец, мы возвращаем строки в их исходный порядок с помощью еще одного переворота.

  4. Сортировка GNU (какпредложенныйот @StéphaneChazelas)

    sort -buk1,1
    

    Флаг -bигнорирует начальные пробелы и -uозначает печать только уникальных полей. Умный момент — -k1,1. -kФлаг задает поле для сортировки. Он принимает общий формат, -k POS1[,POS2]который означает просмотр только полей POS1через POS2 при сортировке. Таким образом, -k1,1означает просмотр только 1-го поля. В зависимости от ваших данных вы можете также добавить одну из этих опций:

     -g, --general-numeric-sort
          compare according to general numerical value
     -n, --numeric-sort
          compare according to string numerical value
    

решение2

Если длина первого столбца всегда составляет 5 символов, вы можете просто использовать uniq:

uniq -w 5 file

Если нет, используйте awk:

awk '$1!=a{print $0; a=$1}' file

Первый вариант определенно будет быстрее с большим файлом.

Связанный контент