Ich habe zwei Dateien mit ungefähr 12900 bzw. 4400 Einträgen, denen ich beitreten möchte. Die Dateien enthalten Standortinformationen für alle landgestützten Wetterbeobachtungsstationen auf der ganzen Welt. Die größte Datei wird alle zwei Wochen aktualisiert, die kleinere etwa einmal im Jahr. Die Originaldateien finden Sie hier ( http://www.wmo.int/pages/prog/www/ois/volume-a/vola-home.htm und http://weather.rap.ucar.edu/surface/). Stationen.txt ). Die Dateien, die ich habe, werden bereits von mir mit einem gemischten awk-, sed- und bash-Skript bearbeitet. Ich verwende die Dateien, um Daten mit dem GEMPAK-Paket zu visualisieren, das bei Unidata frei verfügbar ist. Die größte Datei funktioniert mit GEMPAK, jedoch nur nicht mit allen Funktionen. Hierzu wird ein Join benötigt.
Datei 1 enthält Standortinformationen für Wetterbeobachtungsstationen, wobei die ersten 6 Ziffern die eindeutige Stationskennung sind. Die verschiedenen Parameter (Stationsnummer, Stationsname, Ländercode, Längengrad und Stationshöhe) werden nur durch ihre Position in der Linie definiert, dh ohne Registerkarten.
060090 AKRABERG FYR DN 6138 -666 101
060100 VAGA FLOGHAVN DN 6205 -728 88
060110 TORSHAVN DN 6201 -675 55
060120 KIRKJA DN 6231 -631 55
060130 KLAKSVIK HELIPORT DN 6221 -656 75
060160 HORNS REV A DN 5550 786 21
060170 HORNS REV B DN 5558 761 10
060190 SILSTRUP DN 5691 863 0
060210 HANSTHOLM DN 5711 858 0
060220 TYRA OEST DN 5571 480 43
060240 THISTED LUFTHAVN DN 5706 870 8
060290 GROENLANDSHAVNEN DN 5703 1005 0
060300 FLYVESTATION AALBORG DN 5708 985 13
060310 TYLSTRUP DN 5718 995 0
060320 STENHOEJ DN 5736 1033 56
060330 HIRTSHALS DN 5758 995 0
060340 SINDAL FLYVEPLADS DN 5750 1021 28
Datei 2 enthält die eindeutige Kennung in Datei 1 und eine zweite Kennung mit 4 Zeichen (ICAO-Locator).
060100 EKVG
060220 EKGF
060240 EKTS
060300 EKYT
060340 EKSN
060480 EKHS
060540 EKHO
060600 EKKA
060620 EKSV
060660 EKVJ
060700 EKAH
060780 EKAT
Ich möchte die beiden Dateien verbinden, damit die resultierende Datei den 4-stelligen Bezeichner an den ersten 4 Stellen in der Zeile hat, dh der Bezeichner sollte die 4 Leerzeichen ersetzen.
060090 AKRABERG FYR DN 6138 -666 101
EKVG 060100 VAGA FLOGHAVN DN 6205 -728 88
060110 TORSHAVN DN 6201 -675 55
060120 KIRKJA DN 6231 -631 55
060130 KLAKSVIK HELIPORT DN 6221 -656 75
060160 HORNS REV A DN 5550 786 21
060170 HORNS REV B DN 5558 761 10
060190 SILSTRUP DN 5691 863 0
060210 HANSTHOLM DN 5711 858 0
EKGF 060220 TYRA OEST DN 5571 480 43
EKTS 060240 THISTED LUFTHAVN DN 5706 870 8
060290 GROENLANDSHAVNEN DN 5703 1005 0
EKYT 060300 FLYVESTATION AALBORG DN 5708 985 13
060310 TYLSTRUP DN 5718 995 0
060320 STENHOEJ DN 5736 1033 56
060330 HIRTSHALS DN 5758 995 0
EKSN 060340 SINDAL FLYVEPLADS DN 5750 1021 28
Ist es möglich, diese Aufgabe mit einem Bash- und / oder Awk-Skript auszuführen?
quelle
Antworten:
quelle
Ein paar von uns wollten sehen, ob wir dieses Problem
join
nur mit lösen können . Dies ist mein Versuch, das zu tun. Da es teilweise funktioniert, schuldet mir @Terdon ein Abendessen 8-).Der Befehl
Beispiel
Einzelheiten
Das Obige nutzt so ziemlich jede verfügbare Option,
join
die mir sagt, dass wir sie falsch verwenden, wie auf eine Art Frankenstein-Art, aber wir lernen alle hier, also ist das in Ordnung ... Ich denke.Der Schalter
-a1
weist join an, alle Zeilen, die nicht mit Datei2 übereinstimmen, in Datei1 aufzunehmen. Das ist es also, was diese Zeilen antreibt, um angezeigt zu werden:Die
-1 1
und-2 1
sagen, welche Spalten die Zeilen aus den 2 Dateien verbinden sollen, hauptsächlich ihre 1. Spalten. Das-o ...
sagt, welche Spalten aus den 2 Dateien in welcher Reihenfolge angezeigt werden sollen.Das
-e "N/A"
sagt, dass die Zeichenfolge "N / A" als Platzhalterwert zum Drucken für Felder verwendet werden soll, die von als leer geltenjoin
.Die letzten beiden Argumente speisen die beiden Dateien
file1
&file2
wie im Join-Befehl sortiert.Bitte seien Sie freundlich, da dies eine laufende Arbeit ist und wir versuchen zu demonstrieren, wie man diese Art von Problem mit dem
join
Befehl lösen würde , da dies die Art von Problem zu sein scheint, für die es gedacht war.Offene Fragen
3. Spalte
Das wichtigste ist, wie man mit der 3. Spalte umgeht, da es sich um eine Mischung aus 1 Wort- und 2 Wortwerten handelt. Dies scheint ein großer Stolperstein zu sein
join
und ich kann keinen Weg finden, um es zu umgehen. Jede Anleitung wäre dankbar.Abstand
Der gesamte ursprüngliche Abstand geht verloren
join
und ich sehe auch keine Möglichkeit, ihn beizubehalten. So istjoin
vielleicht nicht der richtige Weg , um mit dieser Art von Problemen nach allem zu beschäftigen.Scheint aber zu funktionieren?
Nach langem Biegen mit der Befehlszeile ist die allgemeine Lösung vorhanden, sodass dies zumindest teilweise funktionieren kann. Dies könnte also im Kern einer Lösung verwendet werden und dann andere Tools wie
awk
undsed
zum Bereinigen verwenden . Dies wirft jedoch die Frage auf: "Wenn Sie es mitawk
& aufsed
irgendeine Weise aufräumen, können Sie sie genauso gut direkt verwenden?".quelle
join
konnte. Jetzt hat das Internet diese. 8-)Dies sollte möglich sein,
join
aber ich kann nicht herausfinden, wie Leerzeichen und leere Felder korrekt gedruckt werden. Wie auch immer, dieses kleine Perl-Skript wird den Trick machen:Speichern Sie dies als
foo.pl
und führen Sie es wie folgt aus:quelle
-o
Funktion noch nie benutzt und nicht so funktioniert, wie ich es erwartet hätte.-o
und-e
konnte es aber nicht dazu bringen, Zeilen zu drucken, die keinen Eintrag in Datei2 hatten. Viel Glück, ich würde gerne wissen, ob es möglich ist.Bash wird es tun.
In dieser SO-Antwort finden Sie Einzelheiten dazu, was mit dem "Hash" passiert. Bash 4 unterstützt nativ assoziative Arrays, dies sollte jedoch in 3 + 4 funktionieren (möglicherweise 2?).
Möglicherweise müssen Sie die Zeile von Datei1 nach links kürzen, um die Formatierung zu erhalten.
quelle
Hier ist eine einfache Möglichkeit, dies mit
join
(+ ein paar weiteren Werkzeugen) zu tun und den Abstand beizubehalten. Beide Dateien scheinen nach Stationsnummer sortiert zu sein, sodass keine zusätzliche Sortierung erforderlich ist:Der Teil vor der Pipe ist dem in seiner Antwort verwendeten Slm sehr ähnlich, daher werde ich nicht noch einmal darauf eingehen . Der einzige Unterschied ist , dass ich mit - einer vierRäume Zeichenfolge als Ersatz für fehlende Eingabefelder und der Ausgabe nur das zweite Feld von file2 So erzeugt eine Vier-Zeichen-breite Spalte (es ist nicht sichtbar unter , aber es gibt nichts nach EK ** und Leerzeilen sind eigentlich vier Leerzeichen):
-e " "
-o 2.2
join -j1 -a1 -o 2.2 -e " " file1 file2
wir dann
paste
dies (mit Leerzeichen als Trennzeichen) zu Datei1, aus der wircut
die ersten 5 Zeichen| paste -d' ' - <(cut -c6- file1)
Endergebnis:
quelle