使用Powershell读取文本文件并查找文本

时间:2017-02-16 10:39:06

标签: powershell

我正在尝试解决一项任务,我认为我可以使用 PowerShell

tutorial我发现我可以读取文本文件并显示如下:

 # C:\Users\Andrew> Get-Content -Path d:\TextToFind.txt

然后,基于另一个tutorial我尝试在文本文件中搜索短语:

 $Path = "D:\My Programs\2017\MeetSchedAssist\Meeting Schedule Assistant"
 $Text = "ID_STR_THIS_VERSION"
 $PathArray = @()
 $Results = "D:\Results.txt"

 # But I want to IGNORE "resource.h"
 # But I want to filter for *.h AND *.cpp
 Get-ChildItem $Path -Filter "*.cpp" | Where-Object { $_.Attributes -ne "Directory"}

 ForEach-Object {
    If (Get-Content $_.FullName | Select-String -Pattern $Text) {
        $PathArray += $_.FullName
        $PathArray += $_.FullName
    }
 }
 Write-Host "Contents of ArrayPath:"
 $PathArray | ForEach-Object {$_}

不能工作:

Error

特别是,我想要做的是:

For each line of text in TextToFind.txt
    Examine all CPP and H files in folder XXX - but ignore RESOURCE.H
    If the file DOES NOT use this line of text
       Append the line of text to a log file.
    End If
End For

我知道写的脚本没有这样做。但是我在最后的障碍中失败了。

更新

根据评论和回答,我试过这个:

# Read in the STRINGTABLE ID values I want to locate
$TextToFind = Get-Content -Path d:\TextToFind.txt

$Path = "D:\My Programs\2017\MeetSchedAssist\Meeting Schedule Assistant"
$Text = "ID_STR_THIS_VERSION"
$PathArray = @()
$Results = "D:\Results.txt"

# But I want to IGNORE "resource.h"
# But I want to filter for *.h AND *.cpp

# First you collect the files corresponding to your filters
$files =  Get-ChildItem $Path -Filter "*.cpp" | Where-Object { $_.Attributes -ne "Directory"}

# Now iterate each of these text values
$TextToFind | ForEach-Object {
    $Text = $_
    Write-Host "Checking for: " $Text

    # Then, you enumerate these files and search for your pattern
    $InstancesFound = $FALSE
    $files | ForEach-Object {
        If ((Get-Content $_.FullName) | Select-String -Pattern $Text) {
            $PathArray += $Text + " " + $_.FullName
            $InstancesFound = $TRUE
        }
    }
    if($InstancesFound -eq $FALSE) {
        $PathArray += $Text + " No instance found in the source code!"
    }
}



Write-Host "Contents of ArrayPath:"
$PathArray | ForEach-Object {$_}

上面唯一的问题是它没有考虑忽略resource.h,我似乎无法过滤.h和.cpp。

2 个答案:

答案 0 :(得分:1)

我想你想要的应该是这样的:

capp deploy
capp my_custom:task

答案 1 :(得分:1)

IMO最简单的方法是在路径上使用Select-String而不是获取内容并找出哪些文件具有匹配的行。

查找搜索文本的所有匹配条目:

$files = (Get-ChildItem -Filter @("*.cpp","*.h") -Exclude "Resource.h"
$matches = ($files|Select-String $text)

如果您再键入$matches,您将看到这是MatchInfo个对象的数组。这意味着您将在其所匹配的文件中的位置具有上下文参考。

如果您只对文件名感兴趣,可以参考,例如将此分组只显示您匹配的唯一文件。

唯一匹配(仅选择文件名)

$uniqueFiles = $matches|Select-Object -Unique FileName

从这里你将有两个数组,一个是您扫描的所有文件,另一个是所有匹配的文件。它们很容易作为一组减去。

如果您想将结果写回文件(结果文件),您可以使用| Set-Content轻松地将结果进行管道传输。

相关问题