过滤给定范围内的坐标

Filter coordinates in a given range

我有数百个带有地理位置的 .out 文件,我将把它们批量导入到 SQLite 数据库中。不过为了节省时间,我只导入一些区间内的地理坐标线。

文件是这样的:

value;value;longitude;latitude;value;value
value;value;longitude;latitude;value;value

所以不在几个纬度和经度区间内的所有内容都应该从文件中删除。

for f in *.out
do
for each line in $f:
    if not longitude >= longitude1 and longitude <= longitude2 
    or longitude >= longitude3 and longitude <= longitude4 or
    longitude>=longitude5 and longitude<=4:
         delete line

我已经包含了一个伪代码来展示一些努力,但我将如何在 Bash、awk、python 或任何最快的方法中做到这一点。

经纬度是这里的第三个和第四个值。我有 21 个纬度间隔,f.ex 69.41 到 70.95(纬度)。

示例输入

63;543534;34,12;59,43;22,80;654,324;139543;
63;25725;5,11;59,43;22,80;36,00;1391212800;
61;5382189;3,66;60,93;68,00;158,00;1391212800;
43;25977000;10,72;67,51;170,70;168,00;1391212800;
61;2000;4,54;60,00;352,50;352,00;1391212800;
53;2504210;6,96;62,89;289,40;511,00;1391212800;
27;2594800;22,35;70,24;14,50;98,00;1391212800;
61;257900;5,13;60,13;321,10;195,00;1391212800;
31;2598;18,76;69,56;230,20;235,00;1391212800;
63;44000;5,84;59,01;226,90;227,00;1391212800;
61;0;4,96;60,57;125,50;129,00;1391212800;
57;2575000;4,88;61,77;113,00;276,00;1391212800;
34;258500;16,58;69,70;18,20;201,00;1391212800;
243;217000;7,18;65,25;283,00;145,00;1391212800;
243;21900;7,20;64,97;44,80;109,00;1391212800;
243;2190516;2,44;58,20;270,50;121,00;1391212800;
243;22000;1,94;58,39;305,20;130,00;1391212800;
243;231067000;1,87;58,09;12,00;122,00;1391212800;
243;311000150;3,54;61,13;166,30;332,00;1391212800;
243;257282000;7,21;64,97;267,10;112,00;1391212800;
243;232758000;1,77;61,43;333,30;337,00;1391212800;
27;231711000;22,42;70,27;99,20;99,00;1391212800;
68;231770000;10,06;58,74;5,40;10,00;1391212800;

纬度间隔为 69.41 到 70.95 的所需输出:

27;2594800;22,35;70,24;14,50;98,00;1391212800;
31;2598;18,76;69,56;230,20;235,00;1391212800;
34;258500;16,58;69,70;18,20;201,00;1391212800;
27;231711000;22,42;70,27;99,20;99,00;1391212800;

请注意,这最好写入新文件或覆盖现有文件。

如果你只有一个间隔要检查,通过它们并比较:

awk -v lat=5 -v min_lat=69.41 -v max_lat=70.95 '
        BEGIN {FS=OFS=";"} 
        {sub(",",".",$lat)} 
        $lat>=min_lat && $lat<=max_lat' file

我用 lat 表示纬度列,因为它在您的编辑中发生了变化。另请注意,这些字段用逗号分隔小数点,因此我将它们替换为点。

测试

$ awk -v lat=5 -v min_lat=69.41 -v max_lat=70.95 'BEGIN {FS=OFS=";"} {sub(",",".",$lat)} $lat>=min_lat && $lat<=max_lat' file
27;1;2594800;22,35;70.24;14,50;98,00;1391212800;
31;3;2598;18,76;69.56;230,20;235,00;1391212800;
34;3;258500;16,58;69.70;18,20;201,00;1391212800;
27;1;231711000;22,42;70.27;99,20;99,00;1391212800;

如果您碰巧有很多最小值和最大值,将它们作为字符串传递并切片,以便您可以检查它们是否在数组中:

awk -v lat=4 -v min="69.41 70.39" -v max="70.95 70.86" '
       BEGIN {FS=OFS=";"; n=split(min,minlat," "); m=split(max,maxlat," ")} 
       {sub(",",".",$lat); 
        for (i=1;i<=n;i++)  {
             if ($lat>=minlat[i] && $lat<=maxlat[i])
               {print; next}
        }
       }' file

这会将间隔读入数组 minlat[]maxlat[],然后将纬度与所有对 (minlat[1], maxlat[1]), (minlat[2], maxlat[2]), ... 进行比较。如果一个匹配,它打印记录并跳到下一个,以防止打印多次。

测试

$ awk -v lat=4 -v min="69.41 70.39" -v max="70.95 70.86" 'BEGIN {FS=OFS=";"; n=split(min,minlat," "); m=split(max,maxlat," ")} {sub(",",".",$lat); for (i=1;i<=n;i++) {if ($lat>=minlat[i] && $lat<=maxlat[i]) {print; next}}}' file
27;2594800;22,35;70.24;14,50;98,00;1391212800;
31;2598;18,76;69.56;230,20;235,00;1391212800;
34;258500;16,58;69.70;18,20;201,00;1391212800;
27;231711000;22,42;70.27;99,20;99,00;1391212800;