連接具有唯一標識符的兩個文件
我有兩個文件,分別包含大約 12900 和 4400 個條目,我想加入它們。這些文件包含全球所有陸基氣象觀測站的位置資訊。最大的文件每兩週更新一次,較小的文件一年左右更新一次。可以在此處找到原始文件(http://www.wmo.int/pages/prog/www/ois/volume-a/vola-home.htm和 http://weather.rap.ucar.edu/surface/站.txt)。我已經使用一些混合的 awk、sed 和 bash 腳本來操作我擁有的文件。我使用這些文件使用 GEMPAK 包來視覺化數據,該包可從 Unidata 免費獲得。最大的文件可以與 GEMPAK 一起使用,但不能使用它的全部功能。為此,需要加入。
文件 1 包含氣象觀測站的位置資訊,其中前 6 位是唯一的站標識符。不同的參數(站號、站名、國家程式碼、緯度經度和站標高)僅由其在行中的位置定義,即沒有選項卡。
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
文件 2 包含文件 1 中的唯一標識符和第二個 4 字元標識符(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
我想加入這兩個文件,這樣生成的文件將在該行的前 4 個位置有 4 個字元的標識符,即標識符應該替換 4 個空格。
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
是否可以使用一些 bash 和/或 awk 腳本來完成這項任務?
awk 'BEGIN { while(getline < "file2" ) { codes[$1] = $2 } } { printf "%4s%s\n", codes[$1], substr($0, 5) }' file1
我們中的一些人想看看我們是否可以
join
僅使用來解決這個問題。這是我的嘗試。由於它部分有效@Terdon 欠我一頓晚餐 8-)。命令
$ join -a1 -1 1 -2 1 -o 2.2 1.1 1.2 1.3 1.4 1.5 1.6 1.7 -e "N/A" \ <(sort file1) <(sort file2)
例子
$ join -a1 -1 1 -2 1 -o 2.2 1.1 1.2 1.3 1.4 1.5 1.6 1.7 -e "N/A" <(sort file1) <(sort file2) | column -t N/A 060090 AKRABERG FYR DN 6138 -666 101 EKVG 060100 VAGA FLOGHAVN DN 6205 -728 88 N/A 060110 TORSHAVN DN 6201 -675 55 N/A N/A 060120 KIRKJA DN 6231 -631 55 N/A N/A 060130 KLAKSVIK HELIPORT DN 6221 -656 75 N/A 060160 HORNS REV A DN 5550 786 N/A 060170 HORNS REV B DN 5558 761 N/A 060190 SILSTRUP DN 5691 863 0 N/A N/A 060210 HANSTHOLM DN 5711 858 0 N/A EKGF 060220 TYRA OEST DN 5571 480 43 EKTS 060240 THISTED LUFTHAVN DN 5706 870 8 N/A 060290 GROENLANDSHAVNEN DN 5703 1005 0 N/A EKYT 060300 FLYVESTATION AALBORG DN 5708 985 13 N/A 060310 TYLSTRUP DN 5718 995 0 N/A N/A 060320 STENHOEJ DN 5736 1033 56 N/A N/A 060330 HIRTSHALS DN 5758 995 0 N/A EKSN 060340 SINDAL FLYVEPLADS DN 5750 1021 28
細節
以上使用了幾乎所有可用的選項,
join
這告訴我的直覺我們用錯了,就像某種科學怪人的方式一樣,但我們都在這裡學習,所以沒關係……我猜。該開關
-a1
告訴 join 包括在 file1 中沒有來自 file2 的相應匹配的任何行。所以這就是驅動這些行顯示的原因:N/A 060330 HIRTSHALS DN 5758 995 0 N/A
-1 1
和-2 1
表示要加入 2 個文件中的行的列,主要是它們的第 1 列。這-o ...
是說要顯示 2 個文件中的哪些列以及按什麼順序顯示。說使用字元串“
-e "N/A"
N/A”作為佔位符值來列印被認為是空的欄位join
。最後 2 個參數提供 2 個文件,
file1
&file2
排序到 join 命令中。請善待,因為這是一項正在進行的工作,我們正在嘗試展示如何使用該命令解決此類問題
join
,因為這似乎是它所要解決的問題類型。顯著的問題
- 第三欄
主要的問題是如何處理第 3 列,因為它是 1 個單詞和 2 個單詞值的混合。這似乎是一個主要的絆腳石
join
,我想不出辦法。任何指導將不勝感激。 2. 間距所有原始間距都失去了
join
,我也沒有辦法保留它。因此join
,畢竟可能不是處理這些類型問題的正確方法。 3. 似乎工作?在使用命令行多次彎曲之後,通用解決方案就在那裡,所以這似乎至少可以部分工作,所以這可以用作解決方案的核心,然後使用其他工具,例如
awk
和sed
清理它.awk
然而,這引出了一個問題:“如果你用&任何方式清理它sed
,那麼你還不如直接使用它們?”。