Erweitern Sie das awk-Skript für mehrere Zeilen in beiden Textdateien und nicht, wenn beide Dateien nur einen einzigen Datensatz haben

Dec 01 2020

Ich kann diese 3 .txt-Ausgabe erzeugen

AA;BB;CC;DD;

aus 2 Textdateien. Beide Dateien haben nur einen einzigen Datensatz

1 .txt

AA;BB;

2 .txt

CC;DD;BB;AA;

Ich benutze dieses awk-Skript.

BEGIN{
  FS=OFS=";"
}
{
  for(i=1;i<=NF;i++){
    if(!seen[$i]++){ val=(val?val OFS:"")$i }
  }
  print val
  delete seen
  val=""
}

Auf diese Weise verwende ich den pasteBefehl, um beide Dateien zu kombinieren und dann die Ausgabe per awkBefehl zu verarbeiten.

paste 1st.txt 2nd.txt | awk -f tst.awk > "3.txt"

Aber was will ich
Ich muss mehr von einem einzigen Datensatz betrachten. Ich versuche dieses Skript für diese Situation anzupassen. Sie können sehen, dass beide Dateien jetzt nicht nur einen einzigen Datensatz haben.

1 .txt

UU;    
AA;BB;
ZZ;KK;

2 .txt

CC;DD;BB;AA;
LL;KK;
GH;ZZ;SS;

Ausgabe 3 .txt, die ich zu generieren versuche, ist dies

UU;
AA;BB;CC;DD;
ZZ;KK;LL;GH;SS;

Verarbeitungslogik:

Der obige Code verwendet nur Literalzeichenfolgen in einer Hash-Suche von Array-Indizes, sodass es egal ist, welche Zeichen Sie in Ihrer Eingabe haben.
Jedoch über Beispielausgabe: Wenn in 2 .txt gibt es gemeinsame Felder auch in 1 .txt.for Beispiel BB;AA;dann müssen Sie sie in einer einzigen Zeile verketten, dh AA;BB;CC;DD; Eine Reihenfolge ist nicht erforderlich, z. B. ist sie nicht relevant, wenn die Ausgabe " BB;AA;DD;CC;Nur Bedingung" ist, dass doppelte Felder in derselben Zeile vermieden werden müssen

Wenn ich "Duplikate vermeiden" sage, meine ich diese Ausgabe vermeiden

AA;BB;CC;DD;BB;AA;

weil die Ausgabe sein sollte

AA;BB;CC;DD;

Antworten

4 User Dec 01 2020 at 15:23

Vielleicht ist es das, was Sie wollen:

BEGIN{FS=OFS=";"}
{sub(/;$/,"")} NR==FNR{ for (i=1;i<=NF;++i) for (j=1;j<=NF;++j) if (j!=i&&!b[$i,$j]++) a[$i,++c[$i]]=$j
    next
}
{
    delete b
    for (i=1;i<=NF;++i)
        ++b[$i] for (i=1;i<=NF;++i) for (j=1;j<=c[$i];++j)
            if (!b[a[$i,j]]++) $(NF+1)=a[$i,j]
    print
}

Verwenden Sie es so:

awk -f script.awk 2.txt 1.txt

Hier sind einige frühere Fragen (vermutlich Ihre - vielleicht möchten Sie sie sich ansehen und daran arbeiten, wie Sie Ihre Frage richtig stellen können):

  • https://superuser.com/q/1600078
  • awk: Beibehaltung der Zeilenreihenfolge und Entfernung doppelter Zeichenfolgen (Spiegel) beim Generieren von Daten
  • https://superuser.com/q/1600557
  • https://superuser.com/q/1601402
  • https://superuser.com/q/1602713
  • https://stackoverflow.com/q/64929865
  • https://superuser.com/q/1604046
  • Dynamische reguläre Ausdrücke in awk
  • Abschneiden von Zeichenfolgen nach dem Ausführen des awk-Skripts