使用shell从标记中提取多个属性

时间:2013-10-19 12:38:26

标签: html regex extract

我试图提取2个属性" lat"和" lon"来自具有以下格式的文件:

<trkpt lat="38.8577288" lon="-9.0997973"/>
<trkpt lat="38.8576367" lon="-9.1000557"/>
<trkpt lat="38.8575259" lon="-9.1006374"/>
...

并获得以下输出:

-9.0997973,38.8577288
-9.1000557,38.8576367
-9.1006374,38.8575259

(是的,lat / lon对是故意倒置的)

我不太了解正则表达式,但在网上浏览,这是我能够实现的:

grep 'lat="[^"]*"' doc.txt | grep -no 'lat="[^"]*"'

output:
1:lat="38.8577288"
2:lat="38.8576367"
3:lat="38.8575259"

我不确定如何解决这个问题...... 在此先感谢您的帮助

3 个答案:

答案 0 :(得分:1)

使用&amp; (您不应该使用正则表达式来解析HTML或XML!)

如果您还没有xmllint,请安装libxml2

for i in {1..3}; do
    lat=$(xmllint --html --xpath "string(//trkpt[$i]/@lat)" file.xml)
    lon=$(xmllint --html --xpath "string(//trkpt[$i]/@lon)" file.xml)
    echo "$lon,$lat"
done < file.xml 2>/dev/null

(如果您的XML是完整有效的XML,则删除--html


请参阅RegEx match open tags except XHTML self-contained tags

答案 1 :(得分:0)

假设格式按此顺序排列,则只需一次通过。

Find:                           Replace:
.+lat="(.+?)".*lon="(.+?)".+    $2,$1

捕获组确保按顺序查找lat和lon,然后抓住引号内的内容。它确保涉及线路的其余部分,以便替换丢弃它。

答案 2 :(得分:0)

尝试使用Python,如下所示:

python -c 'import re; open("dest", "w").write("\n".join([lat + "," + lon for lat, lon in re.findall("""<trkpt lat="([-0-9\.]+)" lon="([-0-9\.]+)"/>""", open("source").read())]))'

其中dest是包含以逗号分隔的lat和lon值的输出文件的路径,source是包含XML样式标记的输入文件的路径。 (这适用于linux shell。)请注意,我假设输入标签格式将非常一致。

那里的正则表达式是<trkpt lat="([-0-9\.]+)" lon="([-0-9\.]+)"/>

如果您没有方便使用Linux shell,或者您更喜欢使用python脚本或以交互方式使用它,那么请使用以下内容进行更简单的方法:

#! /usr/bin/env python

# use the regex module
import re

# read in the file
in_file = open('source').read()

# Find matches using regex
matches = re.findall('<trkpt lat="([-0-9\.]+)" lon="([-0-9\.]+)"/>', in_file)

# make new file lines by combining lat and lon from matches
out_lines = [lat + ',' + lon for lat, lon in matches]

# convert array of strings to single string
out_lines = '\n'.join(out_lines)

# output to new file
open('dest', 'w').write(out_lines)