Existe-t-il une solution Perl ou awk pour ce problème?

J'ai un file d'input ( input.txt ) comme ci-dessous.

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 

Notez que la première ligne ne fait pas partie du file réel, je l'ai ajouté ici pour plus de clarté .

id1 d'extraire les valeurs de l' id1 et de l' id2 à 2 dossiers distincts nommés unique.txt et duplicate.txt .

Si ma valeur de colonne de weight est supérieure à 1,5, cela signifie que j'ai des identifiants en double . Dans ce cas, je vais déplacer la valeur unique.txt vers le file id2 et la valeur id2 vers le file duplicate.txt .

Si ma colonne de poids est inférieure à 1,5, cela signifie que je n'ai pas de valeurs en double. Donc, dans ce cas, je vais déplacer id1 et id2 dans le file unique.txt .

Donc, pour l'input ci-dessus, je m'attends à la sortie comme,

Pour le file unique.txt ,

 53723848 timburnes 764157 ericcartman 56797854 ericcartman 

Pour le file duplicate.txt ,

 12651711 timburnes 53530214 timburnes 52986038 ericcartman 

Je peux find les duplicates en utilisant le code ci-dessous.

Pour get les valeurs supérieures à 1,5 basées sur la 4ème colonne,

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

Maintenant, pour les valeurs supérieures à 1,5, je peux utiliser le code ci-dessous pour merge les identifiants dupliqués en fonction de leurs noms.

  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 

Cependant, je ne suis pas capable d'get le résultat comme je l'aime dans l'approche ci-dessus.

EDIT :

Je cours la command pour mon input comme ci-dessous.

 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 

Je reçois la sortie comme,

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

Cependant, la production que j'attends est,

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

Voici la solution 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 

Avec votre deuxième exemple:

 $ 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 
 $ 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 

Voici un 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 

Je ne vérifie pas les duplicates ici, si je comprends bien votre question, vous l'avez déjà fait et si quelque chose est dupe ou non, cela dépend de la valeur du dernier champ. Si je ne comprends pas quelque chose s'il vous plaît laissez-moi savoir et je vais mettre à jour cela.

Le code ci-dessus produit

 $ cat duplicate.txt 12651711 timburnes 53530214 timburnes 52986038 ericcartman $ cat unique.txt 53723848 timburnes 764157 ericcartman 56797854 ericcartman