将两个其他字符串之间的grep字符串作为分隔符

时间:2015-06-19 13:02:11

标签: regex powershell grep

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

那么,我如何寻找内容?

编辑:我正在寻找list-unstyled<main>之间的网页</main>

那么我为那个grep使用正则表达式吗?或者我是否需要使用PowerShell来获得更多功能?

我可以随意使用PowerShell,但如果这是我唯一的选择,我可以使用便携式软件。

理想情况下,我会得到一个包含页面和行号的报告(.txt或.csv),但是这些页面本身就足够了。

编辑:进展

我现在在PowerShell中有这个

$files = get-childitem -recurse -path w:\test\york\ -Filter *.html 
foreach ($file in $files)
{
$htmlfile=[System.IO.File]::ReadAllText($file.fullName)
$regex="(?m)<main([\w\W]*)</main>"
if ($htmlfile -match $regex) { 
    $middle=$matches[1] 
    [regex]::Matches($middle,"list-unstyled")
    Write-Host $file.fullName has matches in the middle:
}
}

我使用此命令运行.\FindStr.ps1 | Export-csv C:\Tools\text.csv

它在控制台中输出带有字符串的文件名和路径,put不会向CSV添加任何内容。我怎样才能添加它?

3 个答案:

答案 0 :(得分:1)

不要对这样的事情使用字符串匹配。分析DOM。这应该允许您通过选择适当的根元素来排除页眉和页脚。

$ie = New-Object -COM 'InternetExplorer.Application'

$url = '...'
$classname = 'list-unstyled'

$ie.Navigate($url)
do { Start-Sleep -Milliseconds 100 } until ($ie.ReadyState -eq 4)

$root = $ie.Document.getElementsById('content-element-id')
$hits = $root.getElementsByTagName('*') | ? { $_.ClassName -eq $classname }

$hits.Count  # number of occurrences of $classname below content element

答案 1 :(得分:1)

您可以创建适合多行匹配的正则表达式。正则表达式"(?m)<!-- main content -->([\w\W]*)<!-- end content -->"匹配由您的评论分隔的多行内容,(?m)部分表示此正则表达式启用了多行选项。群组([\w\W]*)会在您的评论之间匹配所有内容,还可以查询$matches[1],其中包含您的&#34;主要文字&#34;没有页眉和页脚。

$htmlfile=[System.IO.File]::ReadAllText($fileToGrep)
$regex="(?m)<!-- main content -->([\w\W]*)<!-- end content -->"
if ($htmlfile -match $regex) { 
    $middle=$matches[1] 
    [regex]::Matches($middle,"list-unstyled")
}

这只是您应该如何解析文件的一个示例。您使用要解析的文件名填充$fileToGrep,然后运行此代码段以接收包含该文件中间所有list-unstyled字符串的字符串。

答案 2 :(得分:1)

Ansgar Wiechers' answer所说的是好建议。不要搜索html文件。我没有问题,但值得注意的是,并非所有的html文件都是相同的,正则表达式搜索会产生有缺陷的结果。如果存在了解文件内容结构的工具,则应使用它们。

我想采用一种简单的方法来报告在给定目录中的所有html文件中出现足够文本list-unstyled的所有文件。你希望有2个?所以,如果超过那个,那就足够了。我会做一个更复杂的正则表达式解决方案,但既然你想要行号,我想出了这个妥协。

$pattern = "list-unstyled"
Get-ChildItem C:\temp -Recurse -Filter *.html | 
    Select-String $pattern | 
    Group-Object Path | 
    Where-Object{$_.Count -gt 2} | 
    ForEach-Object{
        $props = @{
            File = $_.Group | Select-Object -First 1 -ExpandProperty Path
            PatternFound = ($_.Group | Select-Object -ExpandProperty LineNumber) -join ";"
        }

        New-Object -TypeName PSCustomObject -Property $props
    }

Select-String是一个类似grep的工具,可以搜索文件中的字符串。它报告文件中的位置行号,我在这里使用它的原因。

您应该在PowerShell控制台上获得如下所示的输出。

File                                                                           PatternFound                                                                  
----                                                                           ------------                                                                  
C:\temp\content.html                                                           4;11;54

其中4,11,54是找到文本的行。代码过滤掉行数小于3的结果。因此,如果您希望在页眉和页脚中使用一次,则应排除这些结果。