2

我在带有 cygwin 的 Windows 计算机上使用 gawk。我想做的是从三列中找到最小值和最大值,两列是纬度和经度,第三列是值。

这是代码:

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%    

我得到的是:

max is 465.053890    
max latitude is 31.846428    
max is 34.877658    
min 19.976970    
min 31.846428    
min 34.877658    

经度和纬度的最小值和最大值相同。如何比较实数?

4

1 回答 1

3

I'm reasonably sure that this line

'gawk "BEGIN {minc =1000} {minlo=1000} {minla=1000}

doesn't do what you think it does. (Frankly, I'm astounded it compiled at all, I don't think it would have in Kernighan AWK.) And a lot of what's going on here is actually in, what, a Window BAT file?

But here are some guesses.

  • I think the line I quoted above sets minc at start time, and then sets minlo and minla every time it reads a line. Better would be

.

 'BEGIN { minc = 1000; minlo = 1000; minla = 1000; } ....

or even

 'BEGIN { minc = minlo = minla = 1000; } ....
  • in AWK you have to watch out a little with comparisons, because if you aren't careful it coerces your numbers to string and does a string compare (ie lexicographic ordering) instead of a numeric compare.

Ack, tried to do this as an answer to a comment. No go.

The reason the first line doesn't work is that AWK lines have the form

PATTERN { code }

where PATTERN is some expression that identifies a set of input records (usually lines) on which the code part operates. There are some special cases, for example BEGIN, which "matches" before the first time is read. Another special case is the empty pattern, which matches every line. So what you had was being interpreted as

BEGIN {minc  =1000}
      {minlo =1000}
      {minla =1000}

So, before the first line of input is processed, minc is set to 1000. Following that, on every input line, minlo and minla are set to 1000. My versions, since they all do the initialization in a BEGIN line, just initialize the values once.

于 2010-11-06T06:04:22.627 回答