Número real em Gawk
-
27-09-2019 - |
Pergunta
Estou usando o GAWK em um computador Windows com Cygwin. O que estou tentando fazer é encontrar min e max de três colunas, duas são LAT e LON e a terceira coluna é o valor.
Este é o código:
echo off
for /f "tokens=1,2,3 delims= " %%a in
('gawk "BEGIN {maxc = 0} {maxlo=0} {maxla=0}
{if ($3>maxc) maxc=$3} {if ($1>maxlo) maxlo=$1} {if ($2>maxla) maxla=$2} END
{print maxc, maxlo, maxla}" %file%.projected')
do (
set maxc=%%a
set maxlo=%%b
set maxla=%%c
)
echo max is %maxc%
echo max is %maxla%
echo max is %maxlo%
for /f "tokens=1,2,3 delims= " %%a in
('gawk "BEGIN {minc =1000} {minlo=1000} {minla=1000}
{if ($3<minc) minc=$3} {if ($1<minlo) minlo=$1} {if ($2<minla) minla=$2} END
{print minc, minlo, minla}" %file%.projected')
do (
set minc=%%a
set minlo=%%b
set minla=%%c
)
echo min %minc%
echo min %minla%
echo min %minlo%
O que recebo é:
max is 465.053890
max latitude is 31.846428
max is 34.877658
min 19.976970
min 31.846428
min 34.877658
O Min e o máximo são os mesmos para o LON e LAT. Como posso comparar números reais?
Solução
Tenho razoavelmente certo de que esta linha
'gawk "BEGIN {minc =1000} {minlo=1000} {minla=1000}
Não faz o que você acha que faz. (Francamente, estou surpreso que isso compilou, não acho que teria em Kernighan Awk.) E muito do que está acontecendo aqui está realmente dentro, o que, uma janela BAT
Arquivo?
Mas aqui estão algumas suposições.
- Eu acho que a linha que citei acima dos conjuntos
minc
no horário de início e depois defineminlo
eminla
toda vez Ele lê uma linha. Melhor seria
.
'BEGIN { minc = 1000; minlo = 1000; minla = 1000; } ....
ou até
'BEGIN { minc = minlo = minla = 1000; } ....
- No Awk, você deve cuidar um pouco com comparações, porque se você não tiver cuidado, ele coerma seus números a secar e faz uma string compare (ou seja, pedidos lexicográficos) em vez de uma comparação numérica.
ACK, tentou fazer isso como resposta a um comentário. Não vá.
A razão pela qual a primeira linha não funciona é que as linhas AWK têm o formulário
PATTERN { code }
onde o padrão é alguma expressão que identifica um conjunto de registros de entrada (geralmente linhas) nas quais a parte do código opera. Existem alguns casos especiais, por exemplo BEGIN
, que "combina" antes da primeira vez é lido. Outro caso especial é o padrão vazio, que corresponde a todas as linhas. Então, o que você tinha estava sendo interpretado como
BEGIN {minc =1000}
{minlo =1000}
{minla =1000}
Então, antes que a primeira linha de entrada seja processada, minc
está definido como 1000. Seguindo Isso, em todo linha de entrada, minlo
e minla
estão definidos como 1000. minhas versões, pois todas elas fazem a inicialização em um BEGIN
linha, basta inicializar os valores uma vez.