Mam dwa pliki z odpowiednio około 12900 i 4400 wpisami, które chcę dołączyć. Pliki zawierają informacje o lokalizacji dla wszystkich lądowych stacji obserwacji pogody na całym świecie. Największy plik jest aktualizowany co dwa tygodnie, a mniejszy raz w roku. Oryginalne pliki można znaleźć tutaj ( http://www.wmo.int/pages/prog/www/ois/volume-a/vola-home.htm i http://weather.rap.ucar.edu/surface/ station.txt ). Pliki, które mam, są już przeze mnie manipulowane za pomocą mieszanego skryptu awk, sed i bash. Pliki używam do wizualizacji danych za pomocą pakietu GEMPAK, który jest swobodnie dostępny z Unidata. Największy plik będzie działał z GEMPAK, ale nie tylko z jego pełnymi możliwościami. W tym celu potrzebne jest połączenie.
Plik 1 zawiera informacje o lokalizacji dla stacji obserwujących pogodę, gdzie pierwsze 6 cyfr to unikalny identyfikator stacji. Różne parametry (numer stacji, nazwa stacji, kod kraju, długość i szerokość geograficzna oraz wysokość stacji) są określone tylko przez jego pozycję w linii, tzn. Brak zakładek.
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
Plik 2 zawiera unikalny identyfikator w pliku 1 i drugi, 4-znakowy identyfikator (lokalizator ICAO).
060100 EKVG
060220 EKGF
060240 EKTS
060300 EKYT
060340 EKSN
060480 EKHS
060540 EKHO
060600 EKKA
060620 EKSV
060660 EKVJ
060700 EKAH
060780 EKAT
Chcę połączyć dwa pliki, aby plik wynikowy miał 4-znakowy identyfikator na pierwszych 4 pozycjach w wierszu, tj. Identyfikator powinien zastąpić 4 spacje.
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
Czy można wykonać to zadanie za pomocą skryptu bash i / lub awk?
źródło
Odpowiedzi:
źródło
Kilku z nas chciało sprawdzić, czy możemy rozwiązać ten problem
join
tylko za pomocą . To jest moja próba zrobienia tego. Ponieważ częściowo działa @Terdon jest mi winien obiad 8-).Komenda
Przykład
Detale
Powyższe wykorzystuje prawie każdą dostępną opcję,
join
która mówi mojemu przeczuciu, że używamy go źle, jak w pewnym sensie Frankensteina, ale wszyscy się tutaj uczymy, więc to jest OK ... Chyba.Przełącznik
-a1
mówi dołączeniu, aby zawierał wszystkie wiersze, które nie mają odpowiadającego dopasowania z pliku2 w pliku1. Oto, co powoduje wyświetlanie tych linii:-1 1
I-2 1
mówią, które kolumny do przyłączenia przewodów od 2 pliki na, głównie ich 1st kolumny.-o ...
Mówi kolumny, które od 2 do wyświetlania plików iw jakiej kolejności.-e "N/A"
Mówi używać znaków „N / A” o wartości uchwytem miejsce drukować na obszarach, które są uznane przez pustyjoin
.Ostatnie 2 argumenty zasilają 2 pliki
file1
ifile2
są posortowane w poleceniu złączenia.Prosimy o uprzejmość, ponieważ jest to praca w toku, a my staramy się zademonstrować, w jaki sposób można rozwiązać ten typ problemu za pomocą
join
polecenia, ponieważ wydaje się, że jest to rodzaj problemu, do którego został przeznaczony.Nierozstrzygnięte problemy
Trzecia kolumna
Najważniejsze to, jak walczyć z trzecią kolumną, ponieważ jest to połączenie 1 słowa i 2 wartości słów. To wydaje się być poważną przeszkodą
join
i nie mogę znaleźć rozwiązania. Wszelkie wskazówki będą mile widziane.Rozstaw
Całe pierwotne odstępy zostały utracone
join
i nie widzę też sposobu na ich obejście. Wjoin
końcu może to nie być właściwy sposób radzenia sobie z tego rodzaju problemami.Wydaje się jednak działać?
Po wielu zgięciach za pomocą wiersza poleceń istnieje ogólne rozwiązanie, więc wydaje się, że może ono działać przynajmniej częściowo, więc można go użyć w centrum rozwiązania, a następnie skorzystać z innych narzędzi, takich jak
awk
i,sed
aby go wyczyścić . Nasuwa się pytanie jednak: „Jeśli jesteś czyszczenia go zawk
&sed
jakikolwiek sposób, to równie dobrze można po prostu wykorzystać je bezpośrednio?”.źródło
join
więc teraz Internet ma taki. 8-)To powinno być możliwe przy użyciu
join
, ale nie mogę dowiedzieć się, jak zrobić to poprawnie wydrukować spacji i pustych pól. W każdym razie ten mały skrypt w Perlu załatwi sprawę:Zapisz to jako
foo.pl
i uruchom w następujący sposób:źródło
-o
funkcji, nie działałem tak, jakbym się spodziewał.-o
i-e
, ale nie mógł go wydrukować linie, które nie miały wpisu plik2. Powodzenia, chciałbym wiedzieć, czy to możliwe.Bash zrobi.
Zobacz tę odpowiedź SO, aby uzyskać szczegółowe informacje na temat tego, co dzieje się z „skrótem” Bash 4 obsługuje natywnie tablicę asocjacyjną, ale powinno to działać w 3 + 4 (może 2?)
Konieczne może być przycięcie w lewo linii z pliku 1, aby uzyskać formatowanie.
źródło
Oto prosty sposób na zrobienie tego
join
(+ kilka dodatkowych narzędzi) i zachowanie odstępów. Wygląda na to, że oba pliki są posortowane według numeru stacji, więc nie jest wymagane dodatkowe sortowanie:Część przed potokiem jest bardzo podobna do tego, co użył SLM w swojej odpowiedzi, więc nie będę jej więcej omawiać. Jedyną różnicą jest to, że używam
-e " "
- ciąg czterech spacji jako zamiennik brakujących pól wejściowych i-o 2.2
do wyprowadzenia tylko 2. pola pliku2Tak więc
join -j1 -a1 -o 2.2 -e " " file1 file2
tworzy kolumnę o szerokości czterech znaków (nie jest widoczna poniżej, ale po EK nie ma nic ** i puste linie to tak naprawdę cztery spacje):my następnie
paste
to (używając spacji jako separatora) do pliku 1, z którego otrzymujemycut
pierwsze 5 znaków| paste -d' ' - <(cut -c6- file1)
Wynik końcowy:
źródło