Gibt es eine Perl- oder Awk-Lösung für dieses Problem?

Gibt es eine Perl- oder Awk-Lösung für dieses Problem?

Ich habe eine Eingabedatei (Eingabe.txt) Wie unten.

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

Beachten Sie, dassdie erste Zeile ist nicht Teil der eigentlichen Datei, ich habe sie hier der Übersichtlichkeit halber hinzugefügt.

Ich versuche, die Werte von id1und id2in 2 separate Dateien namenseinzigartig.txtUndDuplikat.txt.

Wenn mein weightSpaltenwert größer als 1,5 ist, bedeutet das, dass ichdoppelte IDs. In diesem Fall verschiebe ich den id1Wert in unique.txtdie Datei und id2den Wert in duplicate.txtdie Datei.

Wenn meine Gewichtsspalte kleiner als 1,5 ist, bedeutet das, dass ich keine doppelten Werte habe. In diesem Fall verschiebe ich also sowohl als id1auch id2nach einzigartig.txtDatei.

Für die obige Eingabe erwarte ich also die Ausgabe als:

Füreinzigartig.txtDatei,

53723848 timburnes
764157 ericcartman
56797854 ericcartman

FürDuplikat.txtDatei,

12651711 timburnes
53530214 timburnes
52986038 ericcartman

Ich kann die Duplikate mit dem folgenden Code finden.

Um Werte größer als 1,5 basierend auf der 4. Spalte zu erhalten,

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

Jetzt kann ich für Werte größer als 1,5 den folgenden Code verwenden, um die doppelten IDs basierend auf ihren Namen zusammenzuführen.

  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

Mit dem obigen Ansatz gelingt es mir jedoch nicht, die gewünschte Ausgabe zu erzielen.

BEARBEITEN:

Ich führe den Befehl für meine Eingabe wie unten aus.

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 

Ich erhalte die Ausgabe als:

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

Ich erwarte jedoch folgende Ausgabe:

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

Antwort1

Hier ist awkdie Lösung:

$ 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

Zu Ihrem zweiten Beispiel:

$ 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

Antwort2

$ 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

Antwort3

Hier ist eines in 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

Ich suche hier nicht nach Duplikaten. Wenn ich Ihre Frage richtig verstehe, haben Sie das bereits getan und ob etwas ein Duplikat ist oder nicht, hängt vom Wert des letzten Felds ab. Wenn ich etwas falsch verstehe, lassen Sie es mich bitte wissen und ich werde dies aktualisieren.

Der obige Code erzeugt

$ cat duplicate.txt 
12651711 timburnes
53530214 timburnes
52986038 ericcartman

$ cat unique.txt 
53723848 timburnes
764157 ericcartman
56797854 ericcartman

verwandte Informationen