Powershell:将单个文件拆分为多个文件 - 使用字符串匹配条件

Powershell: Split a single file into multiple files - using string match criteria

我有一个包含 1GB 数据的文件。该数据实际上是数以千计的单个迷你文件的十分之一。 我需要提取每个单独的文件并将它们放在自己单独的 Distinct 文件中。 所以基本上,我需要从一个文件到 30K+ 个单独的文件。

这是我的文件的示例。

FILENAM1 VER 1 32 D
10/15/87 09/29/87
PREPARED BY ?????
REVISED BY ?????
DESCRIPTION USER DOMAIN
RECORD FILENAM1 VER 1 D SUFFIX -4541
100 05 ST-CTY-CDE-FMHA-4541 DISPLAY
200 10 ST-CDE-FMHA-4541 9(2) DISPLAY
300 10 CTY-CDE-FMHA-4541 9(3) DISPLAY
400 05 NME-CTY-4541 X(20) DISPLAY
500 05 LST-UPDTE-DTE-4541 9(06) DISPLAY
600 05 FILLER X DISPLAY 1REPORT NO. 08
DATA DICTIONARY REPORTER REL 17.0 09/23/21
PAGE 2 DREPORT 008
RECORD REPORT

-************************************************************************************************************************************ RECORD RECORD ---- D A T E ----
RECORD NAME LENGTH BUILDER TYPE OCCURRENCES UPDATED CREATED
************************************************************************************************************************************ 0
FILENAM2 VER 1 176 D
03/09/98 02/21/84
PREPARED BY ??????
REVISED BY ??????
DEFINITION

我需要根据 VER 在位置 68、69 和 70 的匹配将文件拆分出来。我还需要为每个文件命名。该信息存储在同一行的 2-9 位置。在上面的示例中,该字符串是“FILENAM1”和 FILENAM2。

因此,仅使用上面的示例,我将创建两个输出文件,它们将被命名为 FILENAM1.txt 和 FILENAM2.txt。

由于我有 30K+ 个文件需要拆分,因此手动执行此操作是不可能的。

我有一个脚本可以将一个文件拆分成多个文件,但它不会按位置搜索字符串。

有人能帮我解决这个问题吗?

这是不起作用的脚本。希望我可以屠杀它并得到一些有效的结果....

$InputFile = "C:\COPIES.txt"
$Reader = New-Object System.IO.StreamReader($InputFile)
$OPName = @()
While (($Line = $Reader.ReadLine()) -ne $null) {
    If ($Line -match "VER"(67,3)) {
        $OPName = $Line.(2,8)
        $FileName = $OPName[1].Trim()
        Write-Host "Found ... $FileName" -foregroundcolor green
        $OutputFile = "$FileName.txt"
    }    
    Add-Content $OutputFile $Line
}
                        

提前谢谢你,

-罗恩

我建议使用 switch statement, which offers both convenient and fast line-by-line reading of files via -File and regex-匹配通过 -Regex:

$streamWriter = $null
switch -CaseSensitive -Regex -File "C:\COPIES.txt" {
  '^.(.{8}).{58}VER' { # Start of a new embedded file.
    if ($streamWriter) { $streamWriter.Close() } # Close previous output file.
    # Create a new output file.
    $fileName = $Matches[1].Trim() + '.txt'
    $streamWriter = [System.IO.StreamWriter] (Join-Path $PWD.ProviderPath $fileName)
    $streamWriter.WriteLine($_)
  }
  default { # Write subsequent lines to the same file.
    if ($streamWriter) { $streamWriter.WriteLine($_) }
  }
}
$streamWriter.Close()

注意:使用 [string] 类型的 .Substring() 方法的解决方案也是可能的,但会更冗长。

  • 正则表达式的 ^.(.{8}).{58} 部分匹配每行的前 67 个字符,同时通过捕获组捕获(基于 1 的)第 2 列到第 9 列(文件名)中的字符(.{8}),这使得捕获的文本在 automatic $Matches variable 的索引 [1] 中可用。然后正则表达式的 VER 部分确保只有在第 68 列位置找到 VER 时该行才匹配。

  • 为了高效output-file创建,使用了[System.IO.StreamWriter]个实例,这比line-by-lineAdd-Content调用快得多。此外,对于 Add-Content,您必须确保目标文件不存在,因为现有内容将被附加到。