【问题标题】:Grep string between two html comments in pages页面中两个 html 注释之间的 Grep 字符串
【发布时间】:2015-09-04 18:59:08
【问题描述】:

我必须报告某个 css 类在我们页面内容中出现的次数(超过 10k 页)。问题是,页眉和页脚包含该类,因此 grep 会返回每一页。 (没用)

那么,我该如何获取内容呢?

我在每个页面上都有 <!-- main content --><!-- end content --> 评论。

那么我如何 grep(我什至 grep 吗?)这些 cmets 之间的内容?

这是托管在 linux 服务器上的,我可以访问 Grep、Awk 和 Sed。

理想情况下,我会得到一份报告(.txt 或 .csv),其中包含显示类的页面和行号,但仅列出页面本身就足够了。

谢谢!

【问题讨论】:

标签: bash replace awk sed grep


【解决方案1】:

以下脚本完全按照您的要求执行:打印出现 CSS 类名的文件和行号:

#!/bin/sh
pattern="class=\"([A-Za-z0-9_-]* )*$1( [A-Za-z0-9_-]*)*\""

awk -v pat="$pattern" '
   /<!-- main content -->/ {Y=1}
   /<!-- end content -->/ {Y=0}
   Y && $0 ~ pat {f[FILENAME] = f[FILENAME]" "FNR;}
   END {for (k in f) printf "%s\tlines:%s\n", k,f[k];}
' *.html

另存为class_find.sh这样使用:

class_find.sh 'my_class'

其中my_class 是您要搜索的类名。

输出:

2.html  lines: 7 9
1.html  lines: 5

一些解释:

  • pattern="class=\"([A-Za-z0-9_-]* )*$1( [A-Za-z0-9_-]*)*\"" :搜索 class="my_class"class="others my_class"class="my_class others"
  • /&lt;!-- main content --&gt;/ {Y=1} : 找到这个字符串后,设置标志Y 为真,/&lt;!-- end content --&gt;/ {Y=0} : 设置标志Y 为假
  • Y &amp;&amp; $0 ~ pat {f[FILENAME] = f[FILENAME]" "FNR;} :如果标志 Y 为真,并且在当前行 ($0) 中找到该类的匹配项,则将行号保存到关联数组 f 中,键为文件名。
  • END {for (k in f) printf "%s\tlines:%s\n", k,f[k];} : 读取所有文件后,以漂亮的格式打印结果
  • *.html:对当前目录下的html文件进行操作

【讨论】:

  • 不错的解决方案,但pattern="class=[\"A-Za-z0-9 _-]*$1[\"A-Za-z0-9 _-]*" 的问题是当您class_find.sh 'my_class' 时,它也会匹配class="my_class_small" 和其他变体。
【解决方案2】:
sed '# remove ":" used for counting later, use another char if ":" is part of the class
   s/://g
# load whole file
   H;$!d
   x
# remove header/trailer
   s/.*/<!-- main content -->/\(.*\)/<!-- end content -->.*/\1/
# keep occurence of my class only
   s/MyClass/:/g;s/[^:]//
# count (max 999)
   s/^$/0/;t
   s/:\{100\}/C/g;s/:\{10\}/D/g
   s/^[^C]/0&/;s/\([0C]\)\(:*\)$/\10\2/;s/[^:]$/&0/
   s/\([^0]\)\1\{8\}/9u/g
   s/\([^0]\)\1\{7\}/8u/g
   s/\([^0]\)\1\{6\}/7u/g
   s/\([^0]\)\1\{5\}/6u/g
   s/\([^0]\)\1\{4\}/5u/g
   s/\([^0]\)\1\{3\}/4u/g
   s/\([^0]\)\1\{2\}/3u/g
   s/\([^0]\)\1/2u/g
   s/[CD:]/1/g
   s/u//g
   ' YourFile

多合一(sed 不是计数的冠军,因此您可以使用| wc -c 而不是计数部分(在这种情况下要小心出现 0)

  • 注意类可能在一行中的任何地方(甚至多次),并且类似 HTML 的文件不是每行 1 条指令,而 grep 在计数时会假设这一点(计算行数,而不是行数)

【讨论】:

    【解决方案3】:

    您可以使用 sed 在评论标签之间搜索 CLASS。如果您只想计算结果,则将输出通过管道传输到wc

    sed -n '/<!-- main content -->/,/<!-- end content -->/ s/CLASS/CLASS/p' filename | wc -l
    

    【讨论】:

      猜你喜欢
      • 2014-10-03
      • 2020-10-29
      • 2014-12-08
      • 2019-11-13
      • 2018-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-21
      相关资源
      最近更新 更多