¿Existe una solución perl o awk para este problema?

¿Existe una solución perl o awk para este problema?

Tengo un archivo de entrada (entrada.txt) como abajo.

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

Tenga en cuenta quela primera línea no es parte del archivo real, la agregué aquí para mayor claridad.

Estoy intentando extraer los valores de id1y id2en 2 archivos separados llamadosúnico.txtyduplicado.txt.

Si weightel valor de mi columna es mayor que 1,5, significa que tengoidentificaciones duplicadas. En este caso, moveré el id1valor al unique.txtarchivo y id2el valor al duplicate.txtarchivo.

Si mi columna de peso es inferior a 1,5, significa que no tengo valores duplicados. Entonces, en este caso, moveré ambos id1y id2a único.txtarchivo.

Entonces, para la entrada anterior, espero el resultado como,

Paraúnico.txtarchivo,

53723848 timburnes
764157 ericcartman
56797854 ericcartman

Paraduplicado.txtarchivo,

12651711 timburnes
53530214 timburnes
52986038 ericcartman

Puedo encontrar los duplicados usando el siguiente código.

Para obtener valores superiores a 1,5 según la cuarta columna,

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

Ahora, para valores superiores a 1,5, puedo usar el siguiente código para fusionar los identificadores duplicados según sus nombres.

  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

Sin embargo, no puedo obtener el resultado de la forma que quiero con el método anterior.

EDITAR:

Estoy ejecutando el comando para mi entrada como se muestra a continuación.

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 

Obtengo el resultado como,

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

Sin embargo, el resultado que espero es,

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

Respuesta1

Aquí está awkla solución:

$ 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

Con tu segundo ejemplo:

$ 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

Respuesta2

$ 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

Respuesta3

Aquí hay uno de 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

No estoy buscando duplicados aquí, si entiendo su pregunta correctamente, ya lo ha hecho y si algo es un engaño o no depende del valor del último campo. Si no entiendo algo, hágamelo saber y lo actualizaré.

El código anterior produce

$ cat duplicate.txt 
12651711 timburnes
53530214 timburnes
52986038 ericcartman

$ cat unique.txt 
53723848 timburnes
764157 ericcartman
56797854 ericcartman

información relacionada