Powershell advanced regex to select from file
I would like to search for a pattern in a file which I ca开发者_开发百科n do easily with something like:
gc $filename | select-string $pattern
However once I have found this first pattern, using the location (line) of the first match as a starting point I would then like to start searching for a second pattern. Once the second pattern has been matched I would then like to return all lines between the first and second matches, discarding the matched lines themselves.
Let's say your first pattern is pattern1 and the second pattern is pattern2
then expression would be (?<=pattern1)(.*?)(?=pattern2)
(?<=pattern1)
- this will match prefix pattern but exclude it from capture
(?=pattern2)
- this will match suffix pattern but exclude it from capture
There may be a more elegant way but this will work
function ParseFile
{
param([string] $FileName)
$s = gc $FileName;
for($x = 0 ; $X -lt $s.count; $x++)
{
if(-not $first ){
if($s[$x] -match "1000"){
$first =$x
}
}
else{
if($s[$x] -match "1075"){
$second = $x ;
break;
}
}
}
(($first +1) .. ($second -1))|%{
$ret += $s[$_]
}
return $ret;
}
I've used foreach
with $foreach.Movenext()
:
foreach ($line in (Get-Content $file))
{
if ($line -match $firstTag)
{
do {
$line
$foreach.MoveNext()
} until ($foreach.current -match $secondTag)
continue
}
}
This will simply return each line one by one, but you can do what you like within the do-loop if you need to process the result in some way
Here is my one (a french bricolage ;o) ), imagine the file c:\temp\gorille.txt :
C'est à travers de larges grilles,
Que les femelles du canton,
Contemplaient un puissant gorille,
Sans souci du qu'en-dira-t-on.
Avec impudeur, ces commères
Lorgnaient même un endroit précis
Que, rigoureusement ma mère
M'a défendu de nommer ici...
Gare au gorille !...
Here is the text between "canton" and "endroit"
PS > (((Get-Content -Path C:\temp\gorille.txt) -join "£" | Select-String -Pattern "(?=canton)(.*)(?<=endroit)").matches[0].groups[0].value) -split "£"
canton,
Contemplaient un puissant gorille,
Sans souci du qu'en-dira-t-on.
Avec impudeur, ces commères
Lorgnaient même un endroit
I join all the lines with a special character "£" (choose onather one if used) then use @Alex Aza pattern in CmdLet Select-String
then split again.
$start = select-string -Path $path -pattern $pattern1 -list |
select -expand linenumber
$end = select-string -path $path -pattern $pattern2 |
where-object {$_.linenumber -gt $start} |
sort linenumber -desc |
select -first 1 -expand linenumber
(get-content $path)[$start..($end -2)]
精彩评论