使用唯一标识符连接两个文件

Sta*_*off 9 awk shell-script text-processing columns join

我有两个文件,分别包含大约 12900 和 4400 个条目,我想加入。这些文件包含全球所有陆基气象观测站的位置信息。最大的文件每两周更新一次,较小的文件大约一年更新一次。原始文件可以在这里找到(http://www.wmo.int/pages/prog/www/ois/volume-a/vola-home.htmhttp://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
Run Code Online (Sandbox Code Playgroud)

文件 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
Run Code Online (Sandbox Code Playgroud)

我想加入这两个文件,以便生成的文件将在行的前 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
Run Code Online (Sandbox Code Playgroud)

是否可以使用一些 bash 和/或 awk 脚本来完成此任务?

小智 8

awk 'BEGIN { while(getline < "file2" ) { codes[$1] = $2 } }
     { printf "%4s%s\n", codes[$1], substr($0, 5) }' file1
Run Code Online (Sandbox Code Playgroud)


slm*_*slm 7

我们中的一些人想看看我们是否可以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)
Run Code Online (Sandbox Code Playgroud)

例子

$ 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
Run Code Online (Sandbox Code Playgroud)

细节

以上是利用几乎所有可用的选项join,告诉我的直觉我们使用它是错误的,就像某种科学怪人的方式一样,但我们都在这里学习,所以没关系......我猜。

该开关-a1告诉 join 包含与 file1 中的 file2 没有相应匹配项的任何行。所以这就是促使这些行显示的原因:

N/A   060330  HIRTSHALS         DN          5758  995   0     N/A
Run Code Online (Sandbox Code Playgroud)

-1 1-2 1说的哪些列参加从2个文件中的线条,主要是他们的第一个列。该-o ...是说从2档栏目,其中以显示和。

-e "N/A"说,使用字符串“N / A”作为占位符值来打印用于由视为空字段join

最后 2 个参数用于提供 2 个文件,file1&file2已排序到 join 命令中。

请善待,因为这是一项正在进行的工作,我们正在尝试演示如何使用该join命令解决此类问题,因为这似乎是它所针对的问题类型。

显着的问题

  1. 第三栏

    主要的问题是如何处理第 3 列,因为它是 1 个单词和 2 个单词值的混合。这似乎是一个主要的绊脚石join,我无法找到解决方法。任何指导将不胜感激。

  2. 间距

    所有原始间距都丢失了join,我也看不到保留它的方法。因此join,毕竟可能不是处理这些类型问题的正确方法。

  3. 似乎工作吗?

    在使用命令行进行多次弯曲之后,通用解决方案就在那里,因此看起来它至少可以部分工作,因此可以将其用于解决方案的核心,然后使用其他工具,例如awksed清理它. 不过,这引出了一个问题:“如果你用awk&sed任何方式清理它,那么你还不如直接使用它们?”。

  • @terdon - 是的,这仍然是一个有趣的问题,喜欢一起解决它,希望我们也可以一起解决未来的一些问题。我仍然认为这个答案将在网站上起到有用的作用,因为我找不到很多`join`的极端例子,所以现在互联网上有这个。8-) (2认同)