Abgleichen und Einfügen in die Linie

7

Ich habe also 2 sehr große Textdateien, die aus folgenden Zeilen bestehen:

Zuerst:

Robert:Dillain:Other:Other:Other
Julian:Brude:Other:Other:Other
Megan:Flikk:Other:Other:Other
Samantha:Minot:Other:Other:Other
Jesus:Kimmel:Other:Other:Other

Zweite:

Sb:Minot:amsen
Jbb:Kimmel:verlin
R:Dillain:bodent
Mb:Flikk:kentin
Jb:Brude:kemin

Ich möchte sie beide durch die zweite Spalte (Dillain, Brude usw.) abgleichen und sie in Zeilen wie folgt einfügen:

AUSGABE:

Robert:Dillain:Other:Other:Other:R:Dillain:bodent
Jesus:Kimmel:Other:Other:Other:Jbb:Kimmel:verlin
Samantha:Minot:Other:Other:Other:Sb:Minot:amsen
etc...
etc...

Ich habe darüber nachgedacht, seddies zu verwenden, aber alles, was auf Unix basiert, wäre großartig. Ich hatte kein Glück, einen Weg zu finden, dies selbst zu tun.

user104391
quelle
Ihre Reihenfolge der Ausgabedatensätze scheint nicht der einer der Eingabedateien zu entsprechen - ist das von Bedeutung?
Steeldriver
Wie meinst du? Meinst du, dass es nicht die gewünschte Ausgabe zu sein scheint? Weil es so aussieht, aber ich habe vielleicht etwas verpasst
user104391
Werden alle Linien definitiv gepaart?
Mikeserv

Antworten:

8

Das klingt nach einer Aufgabe für join:

join -t":" -o "1.1,1.2,1.3,1.4,1.5,2.1,2.2,2.3" \
   -j 2 <(sort -k2,2 -t: test1) <(sort -k2,2 -t: test2)

Ausgabe:

Julian:Brude:Other:Other:Other:Jb:Brude:kemin
Robert:Dillain:Other:Other:Other:R:Dillain:bodent
Megan:Flikk:Other:Other:Other:Mb:Flikk:kentin
Jesus:Kimmel:Other:Other:Other:Jbb:Kimmel:verlin
Samantha:Minot:Other:Other:Other:Sb:Minot:amsen

Nervenzusammenbruch:

  • -t Setzen Sie das Feldtrennzeichen auf :
  • -o Druckformat einstellen
  • -j Join auf Spaltennummer 2
  • <(sort -k2,2 -t: file)Datei nach -kzweiter Spalte sortieren -tFeldbegrenzer auf setzen:
devnull
quelle
1
@mikeserv Guter Punkt. Ich habe es mit aktualisiert -k2,2. Ja, es joinist ein lustiges nützliches Tool, das die meisten vergessen, auf dem System zu sein - (ich weiß, dass ich es tue), da ich nicht jeden Tag zwei Dateien zusammenfügen muss. Ich neige dazu, joinso häufig zu verwenden, wie es Sonnenfinsternisse gibt. lol
devnull
5

Dies ist eine einfache Aufgabe für awk:

awk -F':' -vOFS=':' 'NR==FNR{a[$2]=$0;next}{print $0,a[$2]}' file2 file1

Zuerst setzen wir :als Feldtrennzeichen sowohl für Eingabe (mit -F) als auch für Ausgabe (mit OFS). Wenn dann die erste Datei verarbeitet wird ( file2), weisen wir dem mit dem zweiten Feld indizierten Tabellenelement eine ganze Zeile zu. Wenn die nächste nächste Datei ( file1) verarbeitet wird, drucken wir ihre Zeilen und fügen die Zeile aus der vorherigen Datei hinzu, in der sie gespeichert ist a[$2].

jimmij
quelle
2

Mit können sedSie wahrscheinlich tun:

sed 's|[^:]*:\([^:]*\).*|/^[^:]*:\1:/s/$/:&/;t|' file2 | sed -f - file1

... was bedeuten würde, dass ein sedProzess die zweite Datei liest und ein sedSkript zum Bearbeiten der ersten in den sedStandard eines zweiten schreibt . Soweit ich das beurteilen kann, sollten Sie kein Problem damit haben, den Inhalt wörtlich direkt in einen solchen regulären Ausdruck einzufügen. Wenn die Möglichkeit der Eingabe von Metazeichen besteht, gibt es auf dieser Website zahlreiche Antworten, in denen die Möglichkeiten zur Flucht vor diesen Zeichen erläutert werden. Wenn dies jedoch erforderlich sein könnte, würde Folgendes ausreichen:

sed 's|[]&\./*[]|\\&|g;s|...' ... | sed -f - file1

Dennoch ist wahrscheinlich der Namensgeber joindie bessere Lösung - dies soll nur zeigen, wie es geht, sedweil Sie es erwähnt haben.

Wie auch immer, das Skript, für das das zweite sedgilt, file1sieht wie folgt aus (mit einer Zeile ähnlich der unten für jede Zeile in Datei2) :

/^[^:]*:Dillain:/s/$/:R:Dillain:bodent/;t

... was bedeutet, dass, wenn es auf eine Linie trifft, die mit Dillain für das zweite durch Doppelpunkte getrennte Feld übereinstimmt, die Zeichenfolge : R: Dillain: bodent an den Schwanz angehängt werden sollte . Da es wahrscheinlich keinen Sinn macht, weiterhin zu versuchen, eine Zeile zuzuordnen, file1wenn eine Zeile von file2bereits angehängt wurde, tverzweigt der Befehl trailing est jede erfolgreiche Ersetzung einfach weg, sobald sie abgeschlossen ist.

mikeserv
quelle
Seltsam. awkDafür wurde mir das Tag-Abzeichen verliehen: Ich weiß nicht einmal, wie ich es verwenden soll awk.
Mikeserv
0

Durch Python3

#!/usr/bin/python3
import csv
import sys
file1, file2 = sys.argv[1], sys.argv[2]
with open(file2) as second, open(file1) as first:
    second_list = second.readlines()
    first_list = first.readlines()
for line1 in first_list:
    for line2 in second_list:
        if line1.split(':')[1] == line2.split(':')[1]:
            print(line1.strip()+line2.strip())

Kopieren Sie das obige Skript und fügen Sie es in eine Datei mit dem Namen ein script.py. Führen Sie dann das Skript aus, indem Sie den folgenden Befehl auf dem Terminal ausführen.

python3 script.py file1 file2
Avinash Raj
quelle