我有一个非常大的KML文件(超过20000个标记)。它们以数字命名,数字从5开始增加到大约7000到27000。
<Placemark>
<name>7750</name>
<description><![CDATA[converted by:</br><a href="http://gridreferencefinder.com/">GridReferenceFinder.com</a></br>]]></description>
<Point>
<coordinates>-0.99153654,52.225002,0</coordinates>
</Point>
</Placemark>
我想删除任何没有在00或50结束的地标。每隔5米就有一个地标放慢了网站上的一些低端设备的速度。
是否有一些脚本,命令或其他会检查名称的内容,如果它没有以00或50结尾从<Placemark>
到</Placemark>
删除该条目?
你真的会节省我10个小时的工作时间单独删除它们。
答案 0 :(得分:0)
在awk中有类似的东西:
$ awk '
/<Placemark>/ { d=""; b="" } # d is delete, b is buffer, reset both
{ b=b $0 (/<\/Placemark>/?"":ORS) } # gather data to d
!/[50]0</ && /<\/name>/ { d=1 } # if not 50 or 00 set del flag
/<\/Placemark>/ && d!=1 { print b } # print b if not marked delete
' file
它只适用于格式良好的输入,尤其是:
...
</Placemark>
<Placemark>
...
<name>1234</name>
...
不
...
</Placemark><Placemark>
... <!-- or: -->
<name>1234
</name>
...
这是一个丑陋的黑客。有人可能会为你提供更好的东西,但如果它符合你的需要就试试。
答案 1 :(得分:0)
awk '$0 == "<Placemark>" {cnt=cnt+1} {arry[cnt]=arry[cnt]$0"\n";if ($0 ~ /<name>/) {match($0,/[[:digit:]]+/);num=substr($0,RSTART,RLENGTH);numbs[num]=cnt}} END { for ( i in numbs ) {if ( substr(i,length(i)-1,length(i)) == "00" || substr(i,length(i)-1,length(i)) == "50") { print arry[numbs[i]] } } }' filename
备用awk解决方案如上所述。当$ 0 =时,我们首先为数组设置一个计数器。然后我们为文件中的每个Placement元素设置数组arry。在我们这样做时,我们还检查文件中的名称索引。当我们找到这个时,我们模式匹配(匹配函数)中的数字,然后使用它来设置另一个数组麻木,跟踪每个放置元素的计数器的数字。我们最后循环遍历麻木中的每个元素,检查数字以确保它以50或00结束。如果是,则打印arry索引。
答案 2 :(得分:0)
Perl-one liner 解决方案!
我想删除任何不以00或50结尾的地标者
首先是解决方案;匹配除00
或50
^(?:[7-9]\d|[1-2]\d\d)(?!00|50)\d\d$
演示:
^(?:[7-9]\d|[1-2]\d\d)(?!00|50)\d\d$
费斯特测试可以是:
perl -le 'print for grep{ /^(?:[7-9]\d|[1-2]\d\d)(?=00|50)\d\d$/ } 7000..27000'
然后读取整个文件一次:
$/=undef;
然后用while循环读取所有匹配项:
while/<Placemark>\s*?<name>(?:[7-9]\d|[1-2]\d\d)(?!00|50)\d\d.*?<\/Placemark>/sg
s
标记用于单行读取或.
可以匹配换行符,g
用于全局搜索
然后打印匹配(S&
):
perl -lne '$/=undef;print $& while/<Placemark>\s*?<name>(?:[7-9]\d|[1-2]\d\d)(?!00|50)\d\d.*?<\/Placemark>/sg' file
匹配模式:
<Placemark>\s*?<name>(?:[7-9]\d|[1-2]\d\d)(?!00|50)\d\d.*?<\/Placemark>
演示:
<Placemark>\s*?<name>(?:[7-9]\d|[1-2]\d\d)(?!00|50)\d\d.*?<\/Placemark>
注意:
如果你注意到这个部分(?!00|50)
它是一个排除匹配器,通过使用 lookahead ,你可以使它相反,这意味着:
^(?:[7-9]\d|[1-2]\d\d)(?=00|50)\d\d$
仅匹配以00
或50
结尾的内容
因此,您可以使用它在您想要的和您不想要的之间切换。
00
或50
perl -lne '$/=undef;print $& while/<Placemark>\s*?<name>(?:[7-9]\d|[1-2]\d\d)(?!00|50)\d\d.*?<\/Placemark>/sg' file
00
或50
perl -lne '$/=undef;print $& while/<Placemark>\s*?<name>(?:[7-9]\d|[1-2]\d\d)(?!00|50)\d\d.*?<\/Placemark>/sg' file
如果您愿意,可以使用运算符:s/regex-match/substitute-string/
perl -pe '$/=undef;s/<Placemark>\s*?<name>(?:[7-9]\d|[1-2]\d\d)(?!00|50)\d\d.*?<\/Placemark>/==>DELETE<==/sg' file
试验:
输入:
before...
<Placemark>
<name>7700</name>
<description><![CDATA[converted by:</br><a href="http://gridreferencefinder.com/">GridReferenceFinder.com</a></br>]]></description>
<Point>
<coordinates>-0.99153654,52.225002,0</coordinates>
</Point>
</Placemark>
after...
---------
before...
<Placemark>
<name>7701</name>
<description><![CDATA[converted by:</br><a href="http://gridreferencefinder.com/">GridReferenceFinder.com</a></br>]]></description>
<Point>
<coordinates>-0.99153654,52.225002,0</coordinates>
</Point>
</Placemark>
after...
--------
before...
<Placemark>
<name>27650</name>
<description><![CDATA[converted by:</br><a href="http://gridreferencefinder.com/">GridReferenceFinder.com</a></br>]]></description>
<Point>
<coordinates>-0.99153654,52.225002,0</coordinates>
</Point>
</Placemark>
after...
--------
before...
<Placemark>
<name>27651</name>
<description><![CDATA[converted by:</br><a href="http://gridreferencefinder.com/">GridReferenceFinder.com</a></br>]]></description>
<Point>
<coordinates>-0.99153654,52.225002,0</coordinates>
</Point>
</Placemark>
after...
end.
输出:
before...
<Placemark>
<name>7700</name>
<description><![CDATA[converted by:</br><a href="http://gridreferencefinder.com/">GridReferenceFinder.com</a></br>]]></description>
<Point>
<coordinates>-0.99153654,52.225002,0</coordinates>
</Point>
</Placemark>
after...
---------
before...
==>DELETE<==
after...
--------
before...
<Placemark>
<name>27650</name>
<description><![CDATA[converted by:</br><a href="http://gridreferencefinder.com/">GridReferenceFinder.com</a></br>]]></description>
<Point>
<coordinates>-0.99153654,52.225002,0</coordinates>
</Point>
</Placemark>
after...
--------
before...
==>DELETE<==
after...
end.
注2:
您可以使用-i
进行就地编辑
perl -i.bak -pe ' ... the rest of the script ...' file
最好使用perl 5.22
或更高版本