Eu tenho dois arquivos com aproximadamente 12900 e 4400 entradas respectivamente, que desejo ingressar. Os arquivos contêm informações de localização para todas as estações terrestres de observação do tempo em todo o mundo. O arquivo maior é atualizado quinzenalmente e o menor uma vez por ano. Os arquivos originais podem ser encontrados aqui ( http://www.wmo.int/pages/prog/www/ois/volume-a/vola-home.htm e http://weather.rap.ucar.edu/surface/ stations.txt ). Os arquivos que eu já tenho são manipulados por mim com alguns scripts awk, sed e bash misturados. Eu uso os arquivos para visualizar dados usando o pacote GEMPAK, disponível gratuitamente na Unidata. O arquivo maior funcionará com o GEMPAK, mas não apenas com toda a sua capacidade. Para isso, é necessária uma junção.
O arquivo 1 contém informações de localização das estações de observação meteorológica, onde os 6 primeiros dígitos são o identificador exclusivo da estação. Os diferentes parâmetros (número da estação, nome da estação, código do país, longitude da latitude e elevação da estação) são definidos apenas pela sua posição na linha, ou seja, sem tabulações.
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
O arquivo 2 contém o identificador exclusivo no arquivo 1 e um segundo identificador de 4 caracteres (localizador 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
Quero unir os dois arquivos, para que o arquivo resultante tenha o identificador de 4 caracteres nas 4 primeiras posições da linha, ou seja, o identificador deve substituir os 4 espaços.
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
É possível realizar esta tarefa com algum script bash e / ou awk?
fonte
Respostas:
fonte
Alguns de nós queriam ver se poderíamos resolver esse problema usando
join
apenas. Esta é a minha tentativa de fazer isso. Como funciona parcialmente, o @Terdon me deve um jantar 8-).O comando
Exemplo
Detalhes
A descrição acima está fazendo uso de praticamente todas as opções disponíveis, o
join
que diz ao meu intestino que estamos usando errado, como em algum tipo de maneira de Frankenstein, mas todos estamos aprendendo aqui, então tudo bem ... eu acho.A opção
-a1
informa ao join para incluir quaisquer linhas que não tenham uma correspondência correspondente do arquivo2 no arquivo1. Então é isso que está direcionando essas linhas para serem exibidas:O
-1 1
e-2 1
está dizendo em quais colunas juntar as linhas dos 2 arquivos, principalmente suas primeiras colunas. O-o ...
está dizendo que colunas das 2 arquivos para mostrar e em que ordem.O
-e "N/A"
diz para usar a string "N / A" como um valor de espaço reservado para imprimir para campos que são considerados vaziajoin
.Os últimos 2 argumentos estão alimentando os 2 arquivos
file1
efile2
classificados no comando join.Por favor, seja gentil, pois esse é um trabalho em andamento e estamos tentando demonstrar como alguém resolveria esse tipo de problema usando o
join
comando, pois esse parece ser o tipo de problema para o qual foi criado.Questões pendentes
3ª coluna
O principal é como lidar com a terceira coluna, pois é uma mistura de 1 palavra e 2 valores de palavra. Isso parece ser uma grande pedra de tropeço
join
e eu não consigo descobrir uma maneira de contornar isso. Qualquer orientação seria apreciada.Espaçamento
Todo o espaçamento original é perdido
join
e também não vejo uma maneira de mantê-lo por perto. Portanto,join
talvez não seja o caminho certo para lidar com esses tipos de problemas.Parece funcionar?
Depois de muita flexão com a linha de comando, a solução geral está lá, então parece que pode funcionar pelo menos parcialmente; portanto, isso pode ser usado no centro de uma solução e, em seguida, fazer uso de outras ferramentas como
awk
esed
para limpá-la. . Isso levanta a questão, porém: "Se você está limpando-o comawk
&sed
qualquer forma, então você pode muito bem usá-los diretamente?".fonte
join
agora a internet tem esse. 8-)Isso deve ser possível usando,
join
mas não consigo descobrir como fazê-lo imprimir espaços e campos vazios corretamente. De qualquer forma, este pequeno script Perl fará o truque:Salve isso
foo.pl
e execute da seguinte maneira:fonte
-o
recurso antes, não funcionando como eu esperaria.-o
e-e
, mas não poderia obtê-lo para imprimir linhas que não tiveram nenhuma entrada no file2. Boa sorte, eu estaria interessado em saber se é possível.Bash fará.
Veja esta resposta SO para obter detalhes do que está acontecendo com o "hash" O Bash 4 suporta nativamente o array associativo, mas isso deve funcionar em 3 + 4 (talvez 2?)
Pode ser necessário aparar a linha esquerda do arquivo1 para obter sua formatação.
fonte
Aqui está uma maneira simples de fazer isso
join
(+ mais algumas ferramentas) e preservar o espaçamento. Ambos os arquivos parecem ser classificados pelo número da estação, portanto, nenhuma classificação adicional é necessária:A parte anterior ao tubo é muito parecida com a que slm usou em sua resposta, para que eu não volte a examiná-lo. A única diferença é que estou usando
-e " "
- uma string de quatro espaços como substituto para campos de entrada ausentes e-o 2.2
para gerar apenas o segundo campo do arquivo2.Portanto,
join -j1 -a1 -o 2.2 -e " " file1 file2
produz uma coluna com quatro caracteres (não é visível abaixo, mas não há nada depois do EK ** e linhas vazias são na verdade quatro espaços):nós então
paste
(usando o espaço como delimitador) no arquivo1 a partir do qual obtemoscut
os 5 primeiros caracteres| paste -d' ' - <(cut -c6- file1)
Resultado final:
fonte