搜索文件夹在多个文件中的两个字符串之间查找字符串并输出到新文件

时间:2015-08-11 20:48:25

标签: powershell

示例文字

  

桌面硬盘驱动器(S / N:9VMJ31W0)

我想找到文件中的文字

  

9VMJ31W0

附加示例文字

  

服务器硬盘驱动器(S / N:3NM2Y5HB)
  服务器硬盘驱动器(S / N:3NM2YXBD)
  伺服器硬盘驱动器(S / N:6SD1MZFE)
  服务器硬盘驱动器(S / N:3NM2YX1Q)
  服务器硬盘驱动器(S / N:6SD1E8SA)
  伺服器驱动器(S / N:3NM305ZQ)
  服务器硬盘驱动器(S / N:B365P760VG2F)
  服务器硬盘驱动器(S / N:B365P760VG54)

我希望输出文件读取类似这样的内容

  

3NM2Y5HB
  3NM2YXBD
  6SD1MZFE
  3NM2YX1Q
  6SD1E8SA
  3NM305ZQ
  B365P760VG2F
  B365P760VG54

然后将此输出到PowerShell中的文件中。

文件将位于特定文件夹中,搜索子文件夹会很棒但不是必需的。 输出将是单个多行.txt文件。

有没有人有我可以用来执行此操作的示例文件?我发现很多类似的事情,但我没有能够真正完成整个任务。

#Clear output variable
$Output = @()

#Get your files
$Files = Get-ChildItem -Recurse -Path "*" -Exclude "Output.txt"

#Loop through files
$Files | ForEach-Object {
  #Use Regular expression to match the desired serial number string
  $Matched = Get-Content $_.FullName | Select-String -AllMatches 'S\/N:([A-Za-z0-9]*)'

  #Loop through the matched strings
  $Matched | ForEach-Object {
    #Save to $Output the grouped (inner) string i.e. you want "9VMJ31W0" not "S/N:9VMJ31W0"
    $Output += $_.Matches.Groups.Value
  }
}

#Write output to file
$Output | Out-File Output.txt

4 个答案:

答案 0 :(得分:0)

在处理字符串时,有点搜索指向了powershell的SubString方法。有关字符串的详细信息,请参阅this page

PS C:\Scripts\updates> $f = gc C:\Scripts\p.txt

PS C:\Scripts\updates> $f
DESKTOP HARD DRIVE (S/N:9VMJ31W0)
DESKTOP HARD DRIVE (S/N:9VMJ31W1)
DESKTOP HARD DRIVE (S/N:9VMJ31W2)

PS C:\Scripts\updates> $f | GM
(Truncated)
Substring        Method                string Substring(int startIndex), str

PS C:\Scripts\updates> $f.substring(24,8) | out-file C:\Temp\HDDSerials.txt

PS C:\Scripts\updates> Get-Content C:\Temp\HDDSerials.txt
9VMJ31W0
9VMJ31W1
9VMJ31W2

答案 1 :(得分:0)

对于初学者,这将输出“D:\ MyFolder”和子文件夹(-Recurse)中所有文件中包含“DESKTOP HARD DRIVE”的所有行,并将它们附加到“D:\ MyFolder \ Output.txt”

Get-ChildItem -Recurse -Path "D:\MyFolder" -Exclude "Output.txt" |
% {Get-Content $_.FullName | Where-Object {$_ -like '*DESKTOP HARD DRIVE*'} |
Select-Object} | Out-File "D:\MyFolder\Output.txt"

最好将输出发送到单独的文件夹,或使用-Exclude将其排除在处理之外。

答案 2 :(得分:0)

正则表达式是这样做的方法,因为序列号在文件中的位置并不重要,它会找到它:

#Clear output variable
$Output = @()

#Get your files
$Files = Get-ChildItem -Recurse -Path "*" -Exclude "Output.txt"

#Loop through files
$Files | ForEach-Object {
    #Use Regular expression to match the desired serial number string
    $Matched = Get-Content $_.FullName | Select-String -AllMatches 'S\/N:([A-Za-z0-9]*)'

    #Loop through the matched strings
    $Matched | ForEach-Object {
        #Save to $Output the grouped (inner) string i.e. you want "9VMJ31W0" not "S/N:9VMJ31W0"
        $Output += $_.Matches.Groups[1].Value
    }
}

#Write output to file
$Output | Out-File Output.txt

如果你想更具体地匹配" DESKTOP HARD DRIVE(S / N:9VMJ31W0)"而不是只是" S / N:9VMJ31W0"然后你将匹配更改为:

Select-String -AllMatches 'DESKTOP HARD DRIVE \(S\/N:([A-Za-z0-9]*)\)'

答案 3 :(得分:0)

这是一个单行:

  Select-String -Path C:\temp\files\*.txt -Exclude output.txt -Pattern '(?<=S/N:)\w+(?=\))' -AllMatches | 
Select-Object -ExpandProperty matches | 
    Select-Object -ExpandProperty Value |
        Out-File -FilePath C:\temp\files\output.txt -Append 

使用lookbehind查找S\N:后的文字和lookahead的结尾)

注意:这假设您的文字存储在文本文件中*.txt