Mehrere Dateien zusammenführen, basierend auf der gemeinsamen Spalte

946
user1083096

Ich habe mehrere Dateien mit jeweils zwei Spalten:

Zum Beispiel :

file1.txt

ID Value1 1 40 2 30 3 70 

file2.txt

ID Value2 3 50 4 70  9 20  

Und so weiter,

file1230.txt

ID Value150 9 98 10 52 2 71 

Wie füge ich diese Dateien basierend auf der ersten Spalte zusammen (basierend auf den Schnittpunkten zwischen den Dateien)? Meine Ausgabe sollte sein

ID Value1 Value2 Value150 1 40 0 0 2 30 0 71 3 70 50 0 4 0 70 0 9 0 20 98 10 0 0 52 

Könnte jemand mit Hilfe von awk oder Linux-Befehlen helfen?

Vielen Dank.

1

2 Antworten auf die Frage

0
Stephen Rauch

Hier haben Sie eine Möglichkeit, dies mit Python zu tun.

Code:

import sys  columns = [] data = {} ids = set() for filename in sys.argv[1:]: with open(filename, 'rU') as f: key = next(f).strip().split()[1] columns.append(key) data[key] = {} for line in f: if line.strip(): id, value = line.strip().split() try: data[key][int(id)] = value except ValueError as exc: raise ValueError( "Problem in line: '{}' '{}' '{}'".format( id, value, line.rstrip()))  ids.add(int(id))  print('\t'.join(['ID'] + columns))  for id in sorted(ids): line = [] for column in columns: line.append(data[column].get(id, '0')) print('\t'.join([str(id)] + line)) 

Ergebnisse:

ID Value1 Value2 Value150 1 40 0 0 2 30 0 71 3 70 50 0 4 0 70 0 9 0 20 98 10 0 0 52 
Ich kann nicht gut mit Python umgehen und kann den Code nicht verstehen. Frage mich, wie man Eingabedateien gibt. user1083096 vor 6 Jahren 0
`sys.argv [1:]` nimmt alle Dateien von der Kommandozeile. Wenn Sie das obige als "my_file.py" gespeichert haben, verarbeitet `python my_file.py file1.txt file2.txt file3.txt '3 Dateien. Sie können auch `sys.argv [1:]` durch eine von Ihnen erstellte Liste ersetzen. Stephen Rauch vor 6 Jahren 0
Danke ... aber da ich mehr als 1000 Dateien habe, gab ich den Befehl python3 my_file.py * .txt. Es wurde ein Fehler angezeigt user1083096 vor 6 Jahren 0
Irgendein spezieller Fehler? Hat es mit einer oder zwei Dateien funktioniert? Irgendetwas, um weiterzugehen? Stephen Rauch vor 6 Jahren 0
Sogar für zwei Dateien zeigt es den gleichen Fehler user1083096 vor 6 Jahren 0
Es gibt etwas in Ihren Daten, das nicht zu Ihren Beispielen passt. Ich habe einige Fehlerberichte hinzugefügt. Stephen Rauch vor 6 Jahren 0
0
Paulo

Eine Bash-Lösung mit Befehlszeilentools. Die Liste der Eingabedateien war nicht in Ordnung, daher die ls -vAusgabe an cat.

while read line; do if [[ "$line" =~ ID ]]; then array=$ index+=($array) continue else eval $array'[$]=$' fi done <<<"$( cat $(ls -v file[0-9]*.txt) )"  printf ID for name in $; do printf ' %s' $name done echo  max_ind=$( sort -nu file[0-9]*.txt | tail -n1 | cut -d' ' -f1 )  for (( j = 1 ; j <= $max_ind ; j++ )); do for (( i = 0 ; i < ${#index[@]} ; i++ )); do value=$( eval 'echo ${'$'[j]}' ) roll+=$( [ "$value" ] && printf "%-${#index[i]}s " $value || printf "%-${#index[i]}s " 0 ) done [[ "$roll" =~ [^0\ ] ]] && printf '%-4s%s\n' $j "$roll" unset roll done