-
Notifications
You must be signed in to change notification settings - Fork 2
/
Invoke-ContextSplit.ps1
124 lines (91 loc) · 3.79 KB
/
Invoke-ContextSplit.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
function Invoke-ContextSplit {
<#
.Synopsis
The Invoke-ContextSplit command copies the specified file and separates the copy into segments.
The original input file, which remains unaltered, must be a text file.
.Description
The Invoke-ContextSplit command writes the segments to files xx00 . . . xxN.
The Pattern can be an array of regular expressions
The Range can be an array of numbers Invoke-ContextSplit .\LineTest.txt -Range 13,62,100
.Example
Invoke-ContextSplit .\testLog.txt start
Reads testLog.txt and creates a file that contains the segment from the current line up to, but not including,
the line containing the specified pattern. The line containing the pattern becomes the current line.
.Example
Invoke-ContextSplit .\testLog.txt start,stop -Verbose -Prefix log
Sames as the previous example. This matches on two patterns, `start` and `stop`
.Example
Invoke-ContextSplit .\testLog.txt start,stop -Verbose -Prefix log
Sames as the previous example, the filenames generated are log00.txt ... logNN.txt
.Example
Invoke-ContextSplit .\LineTest.txt -Range 11,72,98
Creates four files:
the xx00 file contains lines 1-10
the xx01 file contains lines 11-71
the xx02 file contains lines 72-97
the xx03 file would contain lines 98 to the end if the file
#>
[CmdletBinding()]
param(
[string]$FileName,
[string[]]$Pattern,
[int[]]$Range,
[string]$Prefix = "xx",
[string]$Suffix = "txt"
)
$FileName = Resolve-Path $FileName
$Script:OutputFileName = $Null
$Script:FileCount = 0
function Write-ContextSplitMessage {
Write-Verbose ("{1} [{0,5}] " -f (ls $Script:OutputFileName).Length, $Script:OutputFileName)
}
function Get-Range {
param(
[int[]]$TargetLines
)
function New-Range {
param($StartLine,$EndLine)
[PSCustomObject]@{StartLine=$StartLine;EndLine=$EndLine}
}
$StartLine=1
for($idx=0; $idx -lt $TargetLines.Count; $idx+=1) {
$EndLine=$TargetLines[$idx]-1
New-Range $StartLine $EndLine
$StartLine=$TargetLines[$idx]
}
New-Range $StartLine ([int]::MaxValue)
}
function Set-NextFile {
if($PSCmdlet.MyInvocation.BoundParameters['Verbose'].IsPresent) {
if($Script:OutputFileName -and (Test-Path $Script:OutputFileName)) {
Write-ContextSplitMessage
}
}
$Script:OutputFileName = (Join-Path $pwd ("{0}{1:D2}.{2}" -f $Prefix, $Script:FileCount, $Suffix))
if(Test-Path $Script:OutputFileName) { Clear-Content -Path $Script:OutputFileName }
$Script:FileCount += 1
}
function Set-ContextContent ($line) { $line | Add-Content $Script:OutputFileName }
if($pattern) {
$patterns = $Pattern -join "|"
Set-NextFile
switch -Regex ( [System.IO.File]::ReadAllLines($FileName) ) {
$patterns { Set-NextFile; Set-ContextContent $_ }
default { Set-ContextContent $_ }
}
Write-ContextSplitMessage
}
if($Range) {
$TheRange = Get-Range $Range
Set-NextFile
$lineCount = 0
foreach($line in [System.IO.File]::ReadAllLines($FileName)) {
Set-ContextContent $line
$lineCount+=1
if($lineCount -eq $TheRange[$Script:FileCount-1].EndLine) {
Set-NextFile
}
}
Write-ContextSplitMessage
}
}