Chinaunix

标题: sed/awk指定段落处理效率提高方法,请指教 [打印本页]

作者: gfan2    时间: 2017-07-31 17:34
标题: sed/awk指定段落处理效率提高方法,请指教
在处理XML文件时,需根据外部文件list里的每行的数据,对文件中所有指定的段落进行判断,该段落含有外部文件的数据时则删除该段落,

利用循环处理test.xml文件的方式可以实现,但当test.xml文件特别大时,list文件有几十行条件时,循环test.xml次数太多,系统处理时间太长,因此想请教是否可以只循环test.xml文件一次,即每取出一次段落多次循环判断list来提高效率,不知利用sed或awk是否可行,请各位指教,多谢。

cat list|while read line;do
sed -r '/<url/{:a;N;/<\/url>/!ba;/'$line'/d}' test.xml > temp.xml
mv temp.xml test.xml
done



外部判断条件list文件内容如下:
0.83
0.81
....


test.xml 测试文件内容如下:


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<raml xmlns="raml21.xsd" version="2.1">
<cmData id="1234567890" scope="all" type="ready">

<url>
    <loc>http://www.ucat.cc/index.php?ctl=register</loc>
    <lastmod>2013-11-18</lastmod>
    <changefreq>always</changefreq>
    <priority>0.97</priority>
</url>

<url>
    <loc>http://www.ucat.cc/index.php?ctl=register</loc>
    <lastmod>2013-11-18</lastmod>
    <changefreq>always</changefreq>
    <priority>0.88</priority>
</url>

<url>
    <loc>http://www.ucat.cc/index.php?ctl=register</loc>
    <lastmod>2013-11-18</lastmod>
    <changefreq>always</changefreq>
    <priority>0.93</priority>
</url>

<url>
    <loc>http://www.ucat.cc/index.php?ctl=register</loc>
    <lastmod>2013-11-18</lastmod>
    <changefreq>always</changefreq>
    <priority>0.92</priority>
</url>

<url>
    <loc>http://www.ucat.cc/index.php?ctl=register</loc>
    <lastmod>2013-11-18</lastmod>
    <changefreq>always</changefreq>
    <priority>0.81</priority>
</url>

<url>
    <loc>http://www.ucat.cc/index.php?ctl=register</loc>
    <lastmod>2013-11-18</lastmod>
    <changefreq>always</changefreq>
    <priority>0.83</priority>
</url>

<url>
    <loc>http://www.ucat.cc/index.php?ctl=login</loc>
    <lastmod>2013-11-18</lastmod>
    <changefreq>always</changefreq>
    <priority>0.87</priority>
</url>

</cmData>
</raml>

作者: jason680    时间: 2017-07-31 19:48
回复 1# gfan2

$ cat list
0.83
0.81
0.97
0.88
0.92

$ awk 'FNR==NR{a[$1];next}/<url>/{K=1}!K{print;next}K{s=s$0"\n"}/<\/url>/{t=s;s="";K=0;if(match(t,"priority>([.0-9]+)<",m))if(m[1] in a)next;printf t}' list test.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<raml xmlns="raml21.xsd" version="2.1">
<cmData id="1234567890" scope="all" type="ready">



<url>
    <loc>http://www.ucat.cc/index.php?ctl=register</loc>
    <lastmod>2013-11-18</lastmod>
    <changefreq>always</changefreq>
    <priority>0.93</priority>
</url>




<url>
    <loc>http://www.ucat.cc/index.php?ctl=login</loc>
    <lastmod>2013-11-18</lastmod>
    <changefreq>always</changefreq>
    <priority>0.87</priority>
</url>

</cmData>
</raml>


作者: zxy877298415    时间: 2017-07-31 22:05
回复 1# gfan2


  1. awk -vRS=" $\n"   'FNR==NR{for(i=1;i<=split($0,a,"\n");i++) {b[a[i]]=i}}{match($0,"<priority>([^<]+).*",c);if(!b[c[1]]||$0~/cmData/) print $0}' list.txt test.xml
复制代码


作者: gfan2    时间: 2017-07-31 22:12
偶的神啊,我得好好消化一下,谢谢偶像
作者: gfan2    时间: 2017-07-31 22:56
对了,这个AWK是对位置固定match(t,"priority>([.0-9]+)<",m来判断的,如果LIST文件中每行是些字符串呢,能匹配上的在<url>到</url>的每段中可能位置不固定,那怎么判断是否含有这些字符串然后删掉整个段落呢

作者: moperyblue    时间: 2017-08-01 12:34

  1. sed -r '1{x;s/.*/cat list/e;x};/<url>/{:a;N;/<\/url>/!ba;G;/([0-9]+\.[0-9]+\b).*<\/url>.*\n\1\b/d;s/(<\/url>).*/\1/}' test.xml
复制代码

作者: jason680    时间: 2017-08-01 12:59
回复 5# gfan2

举例,说明...
作者: gfan2    时间: 2017-08-01 13:37
回复 7# jason680


例如 list 文件中是一行行的字符串,不能固定的或有规律判断<url>和</url>间某个位置,只要<url>和</url>间含这些字符,我就删掉这个段落呢,如何实现

cat  list
register
change
last
many



作者: 本友会机友会摄友会    时间: 2017-08-01 14:39
提示: 作者被禁止或删除 内容自动屏蔽
作者: 龙牙地主天    时间: 2017-08-01 14:40
我的代码:
  1. awk -vRS="" 'NR==FNR{for(i=1;i<=NF;i++) a[i]=$i }NR>FNR{for(i in a) b=b==""?a[i]:b"|"a[i] ; if(!match($0,b)) print ; b=""}' list.txt test.xml
复制代码


某大神优化后的代码:
  1. awk -vRS= 'NR==FNR{a=$0a;next}{gsub("\n","|",a)}$5!~a' list.txt test.xml
复制代码





欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2