使用内容定界符作为文件名在PowerShell中拆分文本

时间:2018-07-19 11:30:29

标签: regex powershell

我正在尝试将txt转录拆分为单个文件,每个作品集一个。

该文件被标记为[c. 1r][c. 1v] ... [c. 7v],依此类推。

使用此example,我能够创建一个PowerShell脚本,该脚本使用与每个页面定界符匹配的正则表达式进行魔术处理,但是我似乎完全无法使用该正则表达式来给页面命名。有了这段代码

$InputFile = "input.txt"
$Reader = New-Object System.IO.StreamReader($InputFile)
$a = 1
while (($Line = $Reader.ReadLine()) -ne $null) {
    if ($Line -match "\[c\. .*?\]") {
        $OutputFile = "MySplittedFileNumber$a$Matches.txt"
        $a++
    }    
    Add-Content $OutputFile $Line
}

所有文件都以MySplittedFileNumber1System.Collections.Hashtable.txt而不是匹配项命名,而以"$Matches[0]"命名,该变量不存在或已被-Exclude过滤。

我在执行之前设置$regex的所有尝试似乎无济于事,有人可以向我指出如何获取格式为MySplittedFileNumber[c. 1r].txt的结果文件名。

仅使用\[(c\. .*?)\]作为部分匹配会更好,但是一旦我知道如何检索匹配,我敢打赌我可以找到解决方案。 我可以通过某种方式在1r中进行变量1v $a的设置,但是我宁愿使用txt文件中的变量,因为某些作品集可能在手稿中编号错误,需要保留这个。

原始input.txt的内容:

> [c. 1r]
Text paragraph
text paragraph
...
Text paragraph
[c. 1v]
Text paragraph
text paragraph
...
Text paragraph
[c. 2r]
Text paragraph
text paragraph
...
Text paragraph

所需结果:

MySplittedFileNumber[c. 1r].txt的内容:

> [c. 1r]
    Text paragraph
    text paragraph
    ...
    Text paragraph

MySplittedFileNumber[c. 1v].txt的内容:

> [c. 1v]
    Text paragraph
    text paragraph
    ...
    Text paragraph

MySplittedFileNumber[c. 2r].txt的内容:

> [c. 2r]
    Text paragraph
    text paragraph
    ...
    Text paragraph

2 个答案:

答案 0 :(得分:2)

我试图重现它,但做了一点改动,就起作用了:

$InputFile = "input.txt"
$Reader = New-Object System.IO.StreamReader($InputFile)
$a = 1
While (($Line = $Reader.ReadLine()) -ne $null) {

    If ($Line -match "\[c\. .*?\]") {
        $OutputFile = "MySplittedFileNumber$a$($Matches[0]).txt"
        $a++
    }    
    Out-File -LiteralPath "<yourFolder>\$OutputFile" -InputObject $Line -Append
}
  1. 要在""中调用数组的位置,您必须像这样$($array[number])格式化变量
  2. 要写入文件,您应该提供完整路径,而不仅仅是文件名。

答案 1 :(得分:0)

从PowerShell的版本3 Get-Content开始,cmdlet具有-Raw参数,该参数允许将文件作为一个整体读取为字符串,然后可以使用常规命令将其拆分为多个块(使用{{3 }})。

可以使用相同的RegEx来grep节名称并将其插入目标文件名。

## Q:\Test\2018\07\19\SO_51421567.ps1
##
$RE = [RegEx]'(?=(\[c\. \d+[rv]\]))'

$Sections = (Get-Content '.\input.txt' -raw) -split $RE -ne ''

ForEach ($Section in $Sections){
    If ($Section -Match $RE){
        $Section | Out-File -LiteralPath ("MySplittedFileNumber{0}.txt" -f $Matches[1])
    }
}