BASH从多个csv文件中提取有条件的数据,对数据进行排序并删除双精度,需要加快进程

plicqrtu  于 2023-03-27  发布在  其他
关注(0)|答案(2)|浏览(102)

我有一个业余网站与自行车的轨道。这个网站的目的之一是提供POI的(兴趣点)沿着gpx轨道.我有数百个dbase,与每个一千数据.在那一刻,我创建了一个脚本,搜索POI的范围1公里从一个特定的gpx点,将结果添加到一个文件,排序,删除双打.它的工作原理,但是,由于我需要重复的过程,甚至5000次,每一个单一的轨道,我计划添加到我的网站,这导致了一个非常缓慢的操作。

#!/bin/sh

POI_FILES="poi_files.list"

find Db_Poi_Base/ -type f >"${POI_FILES}"

awk -F,   '$1>12.295 \
    && $1<12.579 \
    && $2>46.186 \
    && $2<46.289 {
        print $0 ",",FILENAME
    }' "${POI_FILES}" > "poi_base.txt"

# Looping from this point to end of script
awk -F,   '$1>13.136357 \
    && $1<13.156357 \
    && $2>45.679686 \
    && $2<45.699686 {
        print $0 ",",FILENAME
    }' "${POI_FILES}" > "poi_base1.txt"

if [ -s "poi_base.txt" && -s "poi_base1.txt" ]
then
    cat poi_base.txt poi_base1.txt |
        awk '!seen[$0]++' > poi_base2.txt
fi

if [ -s "poi_base2.txt" ]
then
    sed 's/\r//' poi_base2.txt > poi_base.txt
fi

首先AWK在已识别的文件中进行搜索,将结果与特定参数进行匹配,然后在找到数据的地方添加逗号和特定数据库的文件名;最后将所有内容保存到txt文件中。
第二个AWK与第一个AWK做相同的事情,只是txt文件名发生了变化。
之后,两个数据文件将被合并并传递给AWK以删除double并创建第三个文件。
最后,将检查数据以删除可能存在于相同行中的^M字符(回车),将结果文件命名为与第一行相同;这让我循环只有3个文件。
从第二个AWK开始,将随着参数的变化而循环,直到要分析的点结束。
原始gpx文件具有以下结构

Index   Lat         Lon     
0   45.689686   N   45° 41.381160' N    13.146357   E   13° 8.781420' E
1   45.689657   N   45° 41.379420' N    13.146311   E   13° 8.778660' E

和Poi的Dbase文件具有以下结构(由逗号分隔的三列csv文件)

9.107150,39.219720,Moto Race Srl Accessori Abbigliament Cagliari>39070651423
9.141090,39.236280,Il Centauro Dei Fratelli Sanna Cocco Cagliari>39070492692
9.176310,39.241830,Planet Motors Aprilia Conce Quartu Sant'elena>39070881179

在目前生成我的脚本,我将导入数据在一个开源的电子表格和管理它与一些公式。例如,把+0.01和-0,01值(1公里)到纬度和经度,以获得搜索范围...
由于一切工作正常,即使令人难以置信的慢,我想知道的是,如果有一种方法来加快,进程.我有,也,尝试工作,甚至,与数组如下

IFS=$'\n'&&i=5491&&readarray -t my_array1 < <(find Db_Poi_Base/ -type f -exec awk -F, '$1>13.136357 && $1<13.156357 && $2>45.679686 && $2<45.699686 {print $0 ",",FILENAME}' {} \;)&&echo durata stimata: 91,5 minuti&&echo riga: $i ;((i=i-1))

readarray -t my_array2 < <(find Db_Poi_Base/ -type f -exec awk -F, '$1>12.946311 && $1<13.346311 && $2>45.489657 && $2<45.889657 {print $0 ",",FILENAME}' {} \;)&& my_array1+=(${my_array2[@]})&&echo riga: $i ;((i=i-1))

第一行部分(IFS=$'\n'&&i=5491&&)用于避免回车,并设置倒计时的变量,以通知脚本正在进行中。每行的第二部分(&&echo riga:$i ;((i=i-1))在回显行号后减少变量。
数组解决方案只能部分工作,因为它没有排序和删除双精度。
预期输出如下

13.143540,45.688900,UD Lignano Sabbiadoro -(H R) Desiree>39043171415, Db_Poi_Base/Ristoranti_Senza_Glutine/Ristoranti_Senza_Glutine.csv
13.140550,45.688220,T La Conchiglia Lignano Sabbiadoro UD>39043173861, Db_Poi_Base/Tabacchi/Tabacchi.csv
13.142680,45.689260,T Sebastianis Laura Lignano Sabbiadoro UD>390431720656, Db_Poi_Base/Tabacchi/Tabacchi.csv
13.144810,45.691160,T Di Bella Salvatore Lignano Sabbiadoro UD>39043173820, Db_Poi_Base/Tabacchi/Tabacchi.csv
13.143750,45.691250,T Gusso Luigi Lignano Sabbiadoro UD>39043170187, Db_Poi_Base/Tabacchi/Tabacchi.csv
13.146660,45.691940,T Zamolo Metullio Lignano Sabbiadoro UD>39043170777, Db_Poi_Base/Tabacchi/Tabacchi.csv
13.148370,45.693080,T Passilongo Mario Lignano Sabbiadoro UD>39043171922, Db_Poi_Base/Tabacchi/Tabacchi.csv

那些起来是我的首要问题;作为次要的好奇心,但真的不是一个伟大的,与电子表格一样,每件事都足够快,是直接在脚本中实现gpx文件,例如使用do while循环,从外部gpx文件读取每一行,并将相关列的数据放入命令序列中。
谢谢你的建议。

esbemjvw

esbemjvw1#

由于两个文件的格式相同,您可以通过简单地执行以下操作来删除重复文件:

cat poi_base.txt poi_base1.txt | sort | uniq |

至于项目的一般概念,我建议为每个兴趣点(POI)分配一个唯一ID,如下所示:

poi_00903|9.107150,39.219720,Moto Race Srl Accessori Abbigliament Cagliari>39070651423
poi_00904|9.141090,39.236280,Il Centauro Dei Fratelli Sanna Cocco Cagliari>39070492692
poi_00905|9.176310,39.241830,Planet Motors Aprilia Conce Quartu Sant'elena>39070881179

该ID可以与自行车/步行路径的ID相关或不相关。
执行单个大规模任务,即在每个路径的坐标检查点的指定范围内识别POI的ID,并在修改后的GPX文件(*.gpx_poi)中的每个项目的行上的附加字段中将其作为附加项目列出。
例如,如果原始GPX文件名为

Montessori_053.gpx

一条位置线是

37   45.689657   N   45° 41.379420' N    13.146311   E   13° 8.778660' E

您可以给予相关的POI文件指定名称

Montessori_053.gpx_poi

并且相关行可以被格式化为(具有坐标)

37   45.689657   N   45° 41.379420' N    13.146311   E   13° 8.778660' E ,poi_00903 poi_00904 poi__00907,poi_00792 poi_00795,poi_0348 poi_01009 poi_01201

或者没有坐标

37,poi_00903 poi_00904 poi__00907,poi_00792 poi_00795,poi_0348 poi_01009 poi_01201

其中,第1、第2、第3分组分别是1 km、3 km和10 km内的P0 I。
将POI“预分析”和预编译将使应用程序的响应速度更快,因为您已经将查找工作减少到只需路径索引匹配即可找到需要提取和显示的相关“POI ID”的位置。
您可能还想创建一个“路线规划”,在其中呈现一个对给定路径沿着所有已识别POI的唯一引用以及一个复选框。然后用户可以保存该原始+已选中列表以供以后参考。当用户选择“开始旅行”作为其旅行时,它会在这些路线沿着的最近点用“pin flag label”突出显示“checked”POI。您可能希望给予选项以重新访问原始列表以更改复选标记选择,如果用户改变了他们的想法,他们可能想访问什么或什么时候。只是一些想法。
你有一个非常好的主意。祝你的项目好运!

klsxnrf1

klsxnrf12#

我找到了一个解决方案,工作,是不优雅,但削减过程时间从2小时到3分钟。
首先,我使用以下命令创建一个文件,减少总数据,只提取特定范围内的数据(最大和最小纬度和经度)。

find Db_Poi_Base/ -type f -exec awk -F, '$1>13.011409 && $1<13.783151 && $2>45.641559 && $2<46.10597 {print $0 ",",FILENAME}' {} > "poi_base-test.txt" \;

然后我改变了上面使用的命令的第一部分,设置为在特定文件中搜索:

find poi_base-test.txt -type f -exec awk -F, '$1>13.136357 && $1<13.156357 && $2>45.679686 && $2<45.699686 {print $0}' {} > "poi_base.txt" \;&&i=5491&&echo Termina tra: $t minuti&&echo riga: $i ;((i=i-1));((t=i/45))

结果是正确的,现在是足够快,我的需要

相关问题