1

我有一个包含 60K+ 行的文本文件。这 60K+ 行实际上是用 Natural 编写的大约 50 个左右的程序。我需要将它们分成单独的程序。我有一个脚本可以完美地解决一个缺陷。输出文件的命名。

每个程序都以“Module Name=”开头,后跟程序的实际名称。我需要拆分程序并使用实际的程序名称保存它们。

使用下面的示例,我想创建两个名为 Program1.txt 和 Program2.txt 的文件,每个文件都包含属于它们的行。我有一个脚本,也在下面,可以正确分隔文件,但我无法辨别捕获程序名称并将其用作输出文件的名称的正确方法。

例子:

Module Name=Program1
....
....
....
END

Module Name=Program2
....
....
....
END

代码:

$InputFile = "C:\Natural.txt"
$Reader = New-Object System.IO.StreamReader($InputFile)
$a = 1
While (($Line = $Reader.ReadLine()) -ne $null) {
    If ($Line -match "Module Name=") {
        $OutputFile = "MySplittedFileNumber$a.txt"
        $a++
    }    
    Add-Content $OutputFile $Line
}
4

2 回答 2

3

结合一个switch语句,它可以有效地逐行读取文件,-File并且可以将每一行与正则表达式-Regex匹配,并使用一个System.IO.StreamWriter实例来有效地写入输出文件:

$outStream = $null

switch -Regex -File C:\Natural.txt {
  '\bModule Name=(\w+)' {   # a module start line
    if ($outStream) { $outStream.Close() }
    $programName = $Matches[1] # Extract the program name.
    # Create a new output file.
    # Important: use a *full* path.
    $outStream = [System.IO.StreamWriter] "C:\$programName.txt"
    # Write the line at hand.
    $outStream.WriteLine($_)
  }
  default {                 # all other lines
    # Write the line at hand to the current output file.
    $outStream.WriteLine($_)    
  }
}
if ($outStream) { $outStream.Close() }

笔记:

  • 该代码假定输入文件中的第一行是Module Name=...一行。

  • 默认情况下,正则表达式匹配不区分大小写,就像 PowerShell 通常一样;添加-CaseSensitive,如果需要。

  • 自动$Matches变量用于从匹配结果中提取程序名称。

于 2021-05-26T20:05:06.667 回答
0

谢谢杰夫!

这是我使用拆分命令的解决方案

$InputFile = "C:\Temp\EMNCP\Natural.txt"
$Reader = New-Object System.IO.StreamReader($InputFile)

$OPName = @()
While (($Line = $Reader.ReadLine()) -ne $null) {
    If ($Line -match "Module Name=") {
        $OPName = $Line.Split("=")
        $FileName = $OPName[1].Trim()
        Write-Host "Found ... $FileName" -foregroundcolor green
        $OutputFile = "$FileName.txt"

    }    
    Add-Content $OutputFile $Line
}
于 2021-05-26T20:20:51.833 回答