Converter coordenadas de GPS com script bash

1

Eu preciso converter para um formato específico algumas coordenadas gps que são a saída da informação exif de uma imagem.

Esta é a saída típica:

exif:GPSLatitude: 10/1, 10/1, 10/1
exif:GPSLatitudeRef: N
exif:GPSLongitude: 10/1, 10/1, 10/1
exif:GPSLongitudeRef: E

e esta é a string que eu preciso obter:

10 10 10N 10 10 10E

Eu consegui fazer isso com o seguinte script:

cat $somefile | sed "s/    /$nul/g" | sed "s/exif:GPSLatitudeRef: /$nul/g" | sed "s/exif:GPSLongitude:/$nul/g" | sed "s/exif:GPSLongitudeRef: /$nul/g" | sed "s/exif:GPSLatitude: /$nul/g" | sed "s/\/1/$nul/g" | sed "s/,/$nul/g" | tr -d '\n'

No entanto, percebi que algumas fotos têm uma saída ligeiramente diferente como esta:

exif:GPSLatitude: 10/1, 10/1, 1099/100
exif:GPSLatitudeRef: N
exif:GPSLongitude: 10/1, 10/1, 1088/100
exif:GPSLongitudeRef: E

Eu entendi que /1 , /10 e /100 (talvez também /1000 ) são denominadores do número anterior.

Dadas as seguintes considerações:

  1. Não preciso de muita precisão, portanto posso perder os dois últimos decimais do último número (por exemplo: 1088/100 pode se tornar 10 em vez de 10.88 );
  2. Eu gostaria de ter essa precisão;
  3. Não estou totalmente certo de que os dois primeiros números das coordenadas (graus e minutos, por exemplo: 10/1 10/1 ) podem ter decimais. Neste caso, a precisão das coordenadas seria totalmente confusa, apontando para um lugar diferente no mundo.

Como posso modificar esse script (e talvez torná-lo um pouco mais elegante) para fazer os cálculos e realmente substituir uma fração por um número com um ponto?

    
por giovi321 11.06.2016 / 19:34

1 resposta

1

É muito complexo fazer isso com sed . Uma ferramenta mais adequada é awk ou bc . Por exemplo, para usar bc , inclua outro sed para converter a entrada em uma seqüência de expressões (10/1) e seqüências de caracteres ("") separadas por ";" ou newline resultando na seguinte entrada para bc:

10/1;" "; 10/1;" "; 1099/100
"N \n"
10/1;" "; 10/1;" "; 1088/100
"E \n"

bc avaliará cada expressão e a saída será 10.00 10.00 10.99N 10.00 10.00 10.88E conforme desejado. Aqui está o sed | bc | tr que você precisa:

sed '1i\
scale=2
/Ref: /s/.$/"& \n"/
s/.*: //
s/,/;" ";/g
' | 
bc | tr -d '\n'

Como alternativa, usando awk , você pode substituir todos os seus comandos sed e tr exatamente assim:

awk '
NF==4 { for(i=2;i<=4;i++){
         split($i,x,"/")
         printf "%s%g",i==2?"":" ",x[1]/x[2]
        }
      }
NF==2 { printf "%s%s",$2,$1~/Lat/?" ":"\n" }'

Isto procura por linhas com 4 campos (separados por espaço em branco) e para os campos 2 a 4 divide o campo $ i (digamos "1099/100") em 2 partes no caractere "/". Em seguida, ele imprime a parte 1 dividida pela parte 2 (x [1] / x [2]) usando o formato geral %g para números. O %s no printf é substituído por nada para o campo 2 e por um espaço para os outros 2 campos. Isso separa os números na saída.

Para linhas com 2 campos (NF == 2), imprime o 2º campo ( $2 ) e se o campo 1 contiver o padrão "Lat", imprime um espaço, ou seja, uma nova linha.

    
por 12.06.2016 / 10:50