0

我有 30 个站点地图文件,如下所示:

<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
    <loc>http://www.A.com/a</loc>
    <lastmod>2013-08-01</lastmod>
    <changefreq>weekly</changefreq>
    <priority>0.6</priority>
</url>
<url>
    <loc>http://www.A.com/b</loc>
    <lastmod>2013-08-01</lastmod>
    <changefreq>weekly</changefreq>
    <priority>0.6</priority>
</url>
...
</urlset>

我想要每个 url 标签每行四列的输出,打印到屏幕上

http://www.A.com/a 2013-08-01 weekly 0.6
http://www.A.com/b 2013-08-01 weekly 0.6 

我使用的方法是 Python BeautifulSoup 来解析标签,但是,性能非常慢,因为那里有 30 多个文件,每个文件有 300,000 行。我想知道是否有可能使用一些 shell AWK 或 SED 来做到这一点,或者......我只是使用了错误的工具来做到这一点。

由于站点地图的格式非常好,可能有一些正则表达式技巧可以绕过它。

任何人都有将 AWK 或 SED 中的记录/行划分为多行而不是换行符的经验?

非常感谢!

4

3 回答 3

2

我绝对不会建议将正则表达式作为解析任意 XML 或 HTML 的一般方法,但既然你说这是格式正确的,那么在这种情况下可能会忽略通常的警告:

sed -n '/^<url>$/{n;N;N;N;s/\n/ /g;s/ *<[a-z]*>//g;s/<\/[a-z]*>/ /g;p}'

这是一个注释版本,解释了正在发生的事情:

sed -n '/^<url>$/ {  # if this line contains only <url>
  n;N;N;N              # read the next 4 lines into the pattern space
  s/\n//g              # remove newlines
  s/ *<[a-z]*>//g      # remove opening tags and the spaces before them
  s/<\/[a-z]*>/ /g     # replace closing tags with a space
  p                    # print the pattern space
}' test.txt

-n选项禁止自动打印图案空间。

于 2013-08-15T22:20:14.607 回答
1

这可能对您有用(GNU sed):

sed '/^<url>/!d;:a;N;/<\/url>/!ba;s/<[^>]*>\s*<[^>]*>/ /g;s/^ \| $//g' file

在模式空间中收集url行,用空格替换标签并删除前导和尾随空格。所有其他行都被删除。

url如果您知道标签之间只有 4 行:

sed '/^<url>/!d;N;N;N;N;s/<[^>]*>\s*<[^>]*>/ /g;s/^ \| $//g' file
于 2013-08-16T07:17:53.400 回答
1

sed 是在单行上进行简单替换的出色工具,其他任何事情只需使用 awk:

$ awk -F'[<>]' '
    /^<\/url>/ { inUrl=0; print line }
    inUrl      { line = line (line?" ":"") $3 }
    /^<url>/   { inUrl=1; line="" }
' file
http://www.A.com/a 2013-08-01 weekly 0.6
http://www.A.com/b 2013-08-01 weekly 0.6
于 2013-08-16T01:39:55.853 回答