如何在bash中删除所有空格,而不是删除换行符?我正在尝试使用以下命令创建文件:
curl -s https://gateblogs.com/sitemap.xml | grep loc | sed 's/<loc>//g' | sed 's/<\/loc>//g'
,问题是我需要删除所有空格,同时保留所有换行符。
答案 0 :(得分:2)
这是awk中的一个:
$ curl ... | awk '/<loc>/{gsub(/<\/?loc>|[[:space:]]/,"");print}'
说明:
awk '
/<loc>/ { # process only lines with loc tag on it
gsub(/<\/?loc>|[[:space:]]/,"") # remove tags and whitespace
print # print
}'
使用xml无能工具处理xml的标准免责声明
修改强>:
我对@rth's answer的评论感到好奇,并进行了一些速度测试。我写了一百万行<loc>https://stackoverflow.com</loc>
的记录:
$ awk 'BEGIN{for(i=1;i<=1000000;i++)print " <loc>https://stackoverflow.com</loc>"}' > tehtest
然后继续测试。最好的三个呈现:
$ time cat tehtest |sed 's/<loc>//g' | sed "s/[[:blank:]]*//g" | sed 's/<\/loc>//g' > out1
real 0m39.973s
user 0m42.288s
sys 0m0.600s
$ time cat tehtest | sed -e 's/<loc>//g' -e 's/[[:blank:]]*//g' -e 's/<\/loc>//g' > out2
real 0m40.366s
user 0m40.220s
sys 0m0.212s
$ time cat tehtest|awk '{gsub(/<\/?loc>|[[:space:]]/,"");print}' > out3
real 0m4.053s
user 0m3.988s
sys 0m0.188s
答案 1 :(得分:1)
这不是一个优雅的解决方案,但您可以使用sed删除任何地方的任何空格或标签。喜欢这个
curl -s https://gateblogs.com/sitemap.xml | grep loc | sed 's/<loc>//g' | sed "s/[[:blank:]]*//g" | sed 's/<\/loc>//g'
修改强>
我感谢@JamesBrown test in his answer。为了表明管道可能比单核应用程序中的多个条件更快,我设计了一个简单的例子。 注意:我设计此示例非常具体,只是为了说明使用管道有利于提高性能的情况。此示例与主要问题略有关联。我可能会得到很多-1但是在管道解决方案更快时显示一个示例可能很有用。
这里生成测试文件的python脚本:
with open("testpipeline","w") as fd:
for l in xrange(10000):
for ins in xrange(200):
fd.write(" <loc> ")
for k in xrange(30):
fd.write(" https://stackoverflow.com")
fd.write(" </loc> ")
fd.write("\n")
测试表明管道的性能优于单核。
$python testpipline.py
$time cat testpipeline |sed 's/<\/loc>.*<loc>//g' | sed "s/[[:blank:]]*//g" > /dev/null
real 0m27.470s
user 0m38.628s
sys 0m1.232s
$ time cat testpipeline |sed -e 's/<\/loc>.*<loc>//g' -e "s/[[:blank:]]*//g" > /dev/null
real 0m38.382s
user 0m37.716s
sys 0m1.132s
最后,如果我们删除cat,它会比单核
快约30%$ time sed 's/<\/loc>.*<loc>//g' testpipeline | sed "s/[[:blank:]]*//g" > /dev/null
real 0m26.611s
user 0m38.468s
sys 0m0.268s
我希望它会有所帮助,有人可以发展直觉,这将有助于决定在某些特定情况下什么是最优解决方案。
答案 2 :(得分:1)
不要尝试使用非XML感知工具来解析XML文件。使用XMLStarlet:
curl -s https://gateblogs.com/sitemap.xml | \
xmlstarlet sel -N sm="http://www.sitemaps.org/schemas/sitemap/0.9" -t -m '//sm:loc' -v . -n <sitemap.xml
...或者,如果您需要在未安装的地方运行,可以使用等效的XSLT模板。如果您有以下内容(当-C
参数传递给xmlstarlet sel
时,XMLStarlet会以编程方式生成,其中包含想要为其生成模板的查询)extract-locs.xslt
:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sm="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:exslt="http://exslt.org/common" version="1.0" extension-element-prefixes="exslt">
<xsl:output omit-xml-declaration="yes" indent="no"/>
<xsl:template match="/">
<xsl:for-each select="//sm:loc">
<xsl:call-template name="value-of-template">
<xsl:with-param name="select" select="."/>
</xsl:call-template>
<xsl:value-of select="' '"/>
</xsl:for-each>
</xsl:template>
<xsl:template name="value-of-template">
<xsl:param name="select"/>
<xsl:value-of select="$select"/>
<xsl:for-each select="exslt:node-set($select)[position()>1]">
<xsl:value-of select="' '"/>
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
...然后你可以从
获得完全相同的输出xsltproc extract-sitemap.xslt - <sitemap.xml
答案 3 :(得分:1)
curl -s <http_address> | hxnormalize -x | hxselect -c "loc"
其中hxnormalize
漂亮打印html文件,hxselect
输出给定元素。 -c
选项输出匹配元素的内容。如果没有−c
,也会打印匹配元素的开始和结束标记。
使用正确的工具完成工作。
答案 4 :(得分:0)
只需添加| column -t
所以,那将是
curl -s https://gateblogs.com/sitemap.xml | grep loc | sed 's/<loc>//g' | sed 's/<\/loc>//g' | column -t