Есть ли решение этой проблемы на Perl или awk?

Есть ли решение этой проблемы на Perl или awk?

У меня есть входной файл (ввод.txt), как показано ниже.

id1      id2       name    weight 
53723848 12651711 timburnes 1.36667
53530214 12651711 timburnes 1.51191
53723848 53530214 timburnes 1.94
764157 52986038 ericcartman 0.861145
56797854 764157 ericcartman 1.35258
56797854 52986038 ericcartman 1.73781

Обратите внимание, чтопервая строка не является частью самого файла, я добавил ее сюда для ясности.

Я пытаюсь извлечь значения id1и id2в 2 отдельных файла с именамиуникальный.txtидубликат.txt.

Если значение моего weightстолбца больше 1,5, это значит, что у меня естьдублирующиеся идентификаторы. В этом случае я перемещу id1значение в unique.txtфайл и id2значение в duplicate.txtфайл.

Если мой столбец веса меньше 1,5, это значит, что у меня нет повторяющихся значений. Поэтому в этом случае я перенесу id1и id2в уникальный.txtфайл.

Итак, для приведенного выше ввода я ожидаю вывода, как,

Дляуникальный.txtфайл,

53723848 timburnes
764157 ericcartman
56797854 ericcartman

Длядубликат.txtфайл,

12651711 timburnes
53530214 timburnes
52986038 ericcartman

Я могу найти дубликаты, используя приведенный ниже код.

Чтобы получить значения больше 1,5 на основе 4-го столбца,

awk -F" " '$4 >= 1.5 { print $1" " $2" " $3" " $4}' file1.txt > Output.txt

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

  perl -ane 'foreach(@F[0..1]){$k{$F[2]}{$_}++}
           END{
                foreach $v (sort keys(%k)){
                    print "$_ " foreach(keys(%{$k{$v}})); 
                    print "$v\n"
                }; 
            } ' Output.txt

Однако при использовании вышеописанного подхода мне не удается получить желаемый результат.

РЕДАКТИРОВАТЬ:

Я запускаю команду для своего ввода, как показано ниже.

awk '{
      if ($4 > 1.5) { 
          if (++dup[$2] == 1)  print $2, $3 > "duplicate.txt"
      } 
      else
          if (++uniq[$1] == 1) print $1, $3 > "unique.txt" 
}' << END
17412193 43979400 ericcartman 2.16667
21757330 54678379 andrewruss 0.55264
END 

Я получаю вывод как,

-bash-3.2$ cat unique.txt
21757330 a.andreev
-bash-3.2$ cat duplicate.txt
43979400 ericcartman

Однако, я ожидаю, что результат будет таким:

cat unique.txt
17412193 ericcartman
21757330 andrewruss
54678379 andrewruss
cat duplicate.txt
43979400 ericcartman

решение1

Вот awkрешение:

$ awk '
    $4 < 1.5 {
      uniq[$1] = $3;
      uniq[$2] = $3;
      next;
  }
  {
      uniq[$1] = $3;
      dup[$2] = $3;
      delete uniq[$2];
  }
  END {
    print "--unique.txt--";
    for(i in uniq) {
        print i,uniq[i]
    }
    print "";
    print "--duplicate.txt--";
    for(i in dup) {
        print i,dup[i]
    }
    }' file
--unique.txt--
764157 ericcartman
56797854 ericcartman
53723848 timburnes

--duplicate.txt--
53530214 timburnes
52986038 ericcartman
12651711 timburnes

Во втором примере:

$ awk '
    $4 < 1.5 {
      uniq[$1] = $3;
      uniq[$2] = $3;
      next;
  }
  {
      uniq[$1] = $3;
      dup[$2] = $3;
      delete uniq[$2];
  }
  END {
    print "--unique.txt--";
    for(i in uniq) {
        print i,uniq[i]
    }
    print "";
    print "--duplicate.txt--";
    for(i in dup) {
        print i,dup[i]
    }
    }' << END
> 17412193 43979400 ericcartman 2.16667
> 21757330 54678379 andrewruss 0.55264
END
--unique.txt--
21757330 andrewruss
54678379 andrewruss
17412193 ericcartman

--duplicate.txt--
43979400 ericcartman

решение2

$ awk '{
      if ($4 > 1.5) { 
          if (++dup[$2] == 1)  print $2, $3 > "duplicate.txt"
      } 
      else
          if (++uniq[$1] == 1) print $1, $3 > "unique.txt" 
}' << END
53723848 12651711 timburnes 1.36667
53530214 12651711 timburnes 1.51191
53723848 53530214 timburnes 1.94
764157 52986038 ericcartman 0.861145
56797854 764157 ericcartman 1.35258
56797854 52986038 ericcartman 1.73781
END

$ cat unique.txt 
53723848 timburnes
764157 ericcartman
56797854 ericcartman

$ cat duplicate.txt 
12651711 timburnes
53530214 timburnes
52986038 ericcartman

решение3

Вот пример на Perl:

perl -lane '$F[3]>1.5 ? print STDERR "$F[1] $F[2]" : print STDOUT "$F[0] $F[2]"'\
 input.txt 2> duplicate.txt > unique.txt

Я не проверяю здесь дубликаты, если я правильно понял ваш вопрос, вы уже это сделали, и является ли что-то дубликатом или нет, зависит от значения последнего поля. Если я что-то не понимаю, пожалуйста, дайте мне знать, и я обновлю это.

Код выше производит

$ cat duplicate.txt 
12651711 timburnes
53530214 timburnes
52986038 ericcartman

$ cat unique.txt 
53723848 timburnes
764157 ericcartman
56797854 ericcartman

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