从一组文件中查找字符串

时间:2018-01-19 18:02:35

标签: powershell

我有一组txt文件包含类似的字符串:

Windows 7 Professional Service Pack 1
Product Part No.: *****
Installed from 'Compliance Checked Product' media.
Product ID: 0000-0000-0000  match to CD Key data
CD Key: xxxxx-xxxxx-xxxxx-xxxxx-xxxxx
Computer Name: COMP001
Registered Owner: ABC
Registered Organization:

Microsoft Office Professional Edition 2003
Product ID: 00000-00000-00000-00000
CD Key: xxxxx-xxxxx-xxxxx-xxxxx-xxxxx

如何一次选择所有办公室密钥并保存到另一个文件中?

我的代码:

$content = Get-ChildItem -Path 'S:\New folder' -Recurse |
           where Name -like "b*" |
           select name
Get-Content $content

我得到一个文件名列表但不会为Get-Content运行。

4 个答案:

答案 0 :(得分:1)

您发布的代码不起作用,因为tid包含一个自定义对象列表,其中一个属性($content)仅包含没有路径的文件名。由于您显然没有在当前工作目录中列出文件,而是列出其他文件夹(name),因此如果您希望能够使用这些文件(属性S:\New Folder),则需要这些文件的完整路径读他们。此外,该属性不会自动扩展。您必须在枚举文件时展开它:

FullName

或将值传递给$content = Get-ChildItem -Path 'S:\New folder' -Recurse | Where-Object { $_.Name -like "b*" } | Select-Object -Expand FullName Get-Content $content

Get-Content

除此之外,您所拥有的代码甚至都没有尝试提取您正在寻找的数据。假设文件中的许可证信息块始终由2个或更多连续换行符分隔,您可以在连续换行符时拆分文件内容,并使用如下正则表达式提取信息:

$content = Get-ChildItem -Path 'S:\New folder' -Recurse |
           Where-Object { $_.Name -like "b*" } |
           Select-Object FullName
Get-Content $content.FullName

Get-ChildItem -Path 'S:\New folder' -Recurse | Where-Object { -not $_.PSIsContainer -and $_.Name -like "b*" } | ForEach-Object { # split content of each file into individual license information fragments (Get-Content $_.FullName | Out-String) -split '(\r?\n){2,}' | Where-Object { # filter for fragments that contain the string "Microsoft Office" and # match the line beginning with "CD Key: " in those fragments $_ -like '*Microsoft Office*' -and $_ -match '(?m)(?<=^CD Key: ).*' } | ForEach-Object { # remove leading/trailing whitespace from the extracted key $matches[0].Trim() } } | Set-Content 'C:\output.txt' 是一个匹配2个或更多连续换行符(Windows和Unix样式)的正则表达式。

(\r?\n){2,}是一个正则表达式,它匹配以字符串(?m)(?<=^CD Key: ).*开头的行,并返回该字符串后面的其余行。 CD Key:是一个所谓的正向lookbehind断言,用于匹配模式而不将其包含在返回值中。 (?<=...)是一个正则表达式选项,允许(?m)匹配多行字符串中的行的开头,而不仅仅是字符串的开头。

答案 1 :(得分:0)

尝试这样的事情:

Get-ChildItem "c:\temp" -file -filter "*.txt" | 
    %{select-string -Path $_.FullName -Pattern "CD Key:" } | select line | export-csv "c:\temp\found.csv" -notype

答案 2 :(得分:0)

如果你想要计算机信息,你可以这样做(-context前面有N行,后面是M行-context 3,2前3和后2):

Get-ChildItem "c:\temp" -file -filter "*.txt" | 
    %{select-string -Path $_.FullName -Pattern "CD Key:" -context 6,0  } | where {$_.Context.PreContext[0] -like 'Computer Name:*'} |
        select Line, @{Name="Computer";E={($_.Context.PreContext[0] -split ':')[1] }} | export-csv "c:\temp\found.csv" -notype

答案 3 :(得分:0)

或经典:

Get-ChildItem "c:\temp" -file -filter "*.txt" | foreach{

$CurrenFile=$_.FullName

#split current file rows to 2 column with ':' like delimiter
$KeysValues=get-content $CurrenFile | ConvertFrom-String -Delimiter ":"  -PropertyNames Key, Value

#if file contains CD Key, its good file
if ($KeysValues -ne $null -and $KeysValues[2].Key -eq 'CD Key')
{
    #build object with asked values
    $Object=[pscustomobject]@{

    File=$CurrenFile
    ComputerName=$KeysValues[3].Value
    OfficeKey=$KeysValues[7].Value
    }

    #send objet to standard output
    $Object
}

} | export-csv "c:\temp\found.csv" -notype