Fetch line starting with a specific string in powershell - regex

I am executing a command for which I am getting output like below
Identifier: 3 SFP
Connector: 7 LC
Transceiver: 7004404000000000 4,8,16_Gbps M5 sw Short_dist
Encoding: 6 64B66B
Baud Rate: 140 (units 100 megabaud)
Length 9u: 0 (units km)
Length 9u: 0 (units 100 meters)
Length 50u (OM2): 3 (units 10 meters)
Length 50u (OM3): 10 (units 10 meters)
Length 62.5u:0 (units 10 meters)
Length Cu: 0 (units 1 meter)
Vendor OUI: 00:05:1e
Vendor PN: 57-0000088-01
Vendor Rev: A
Wavelength: 850 (units nm)
Options: 003a Loss_of_Sig,Tx_Fault,Tx_Disable
BR Max: 0
BR Min: 0
Date Code: 180316
DD Type: 0x68
Enh Options: 0xfa
Status/Ctrl: 0xb2
Pwr On Time: 3.52 years (30822 hours)
E-Wrap Control: 0
O-Wrap Control: 0
Alarm flags[0,1] = 0x5, 0x40
Warn Flags[0,1] = 0x5, 0x40
Temperature: 32 Centigrade
Current: 8.082 mAmps
Voltage: 3311.6 mVolts
RX Power: -5.5 dBm (280.4uW)
TX Power: -2.8 dBm (523.1 uW)
I need to fetch the last 2 lines only, that is starting with RX and TX out of it.
I was trying like
#$streamOut | Select-String -Pattern "^RX" | select -ExpandProperty line
$streamOut | Select-String -Pattern "RX" | select -ExpandProperty line
This is by code
$session = New-SSHSession -ComputerName $SAN_IP -Credential $cred
$Strem = New-SSHShellStream -SSHSession $Session
$streamOut=#()
$SystemView = $Strem.WriteLine("sfpshow $port_Num")
sleep -Seconds 5
$streamOut = #($Strem.read())
sleep -Seconds 5
$RXTX_Data = #($streamOut | ? { $_ -match "^RX" -or $_ -match "^TX"})
$RXTX_Data
When I use the below solution in above code, it is returning blank. the $streamOut is array
PS C:\Windows\system32> $streamOut.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
But it is returning the entire output.
Please let me know on this

As you clarified, the $streamOut variable contains a single, multiline string.
In this case you can use Select-String with -AllMatches like this:
$RXTX_Data = ($streamOut | Select-String -Pattern '(?m)^(RX|TX).*$' -AllMatches).Matches.Value
$RXTX_Data # Output array of matching lines
Output:
RX Power: -5.5 dBm (280.4uW)
TX Power: -2.8 dBm (523.1 uW)
Note that it is important to use the (?m) inline modifier for multiline mode, which changes behaviour of ^ to anchor beginning of line and $ to anchor end of line, instead of beginning and end of whole input string.
An easier alternative is to split the string into lines first, so you can use the -match operator to filter for matching lines:
$streamLines = $streamOut -split '\r?\n'
$RXTX_Data = $streamLines -match '^(RX|TX)'
This works because -match and other comparison operators act as a filter when the LHS operand is a collection like an array. We don't need multiline mode, because the RegEx gets applied to each array element (line) individually.
The above two lines could even be condensed into a one-liner:
$RXTX_Data = ($streamOut -split '\r?\n') -match '^(RX|TX)'

try this :
$streamOut = Get-Content -Path "Your_Output_FilePath"
$streamOut | ? { $_ -match "^RX" -or $_ -match "^TX"}

Related

Keep the $character in regular expression replace

Two problems of regular replace
1.need to keep the front $character in the replacement result
2.Skipping the first two lines and the last line is not valid
Code:
$str = #'
#$start1 Random characters
#$start2 Random characters
$p1.AppendBreak($BreakType.LineBreak)
$doc.Protect($ProtectionType.AllowOnlyRevisions, "123")
$footerPara.AppendField("page", $FieldType.FieldPage)
$footerParagraph.AppendField("number of pages", $FieldType.FieldSectionPages)
$txtWatermark.Layout = $WatermarkLayout.Diagonal
$tr1.CharacterFormat.Border.BorderType = $BorderStyle.DashDotStroker
$stri.CharacterFormat.TextBackgroundColor = $Color.LightGray
$document.LoadFromFile(".\Template_HtmlFile.html", $FileFormat.Html, $XHTMLValidationType.None)
$docObject.DocumentObjectType -eq $DocumentObjectType.Picture
$document.Sections[0].Paragraphs[0].InsertSectionBreak($SectionBreakType.NoBreak)
$footerParagraph.Format.HorizontalAlignment = $Spire.Doc.Documents.HorizontalAlignment.Right
#end Random characters
'#
$str | Foreach-Object {
$_ -replace '\$\w+\.(\w+)', '"$1"'
} | Set-Content .\ok.txt
<# -Skip -SkipLast not valid
$str | Foreach-Object {
$_ -replace '\$\w+\.(\w+)', '"$1"'
} | Select-Object -Skip 2 | Select-Object -SkipLast 1 | Set-Content .\ok.txt
#>
Expected results:
At least for your example here string, you need to break it into a string array. Then for the replacement I was only successful when capturing both the beginning and the desired changed text.
$str -split '\r?\n' | Select-Object -Skip 2 |
Select-Object -SkipLast 1 | Foreach-Object {
$_ -replace '(^.+?)\$.+\.(\w+)', '$1"$2"'
} | Set-Content .\ok.txt
Contents of ok.txt
$p1.AppendBreak("LineBreak")
$doc.Protect("AllowOnlyRevisions", "123")
$footerPara.AppendField("page", "FieldPage")
$footerParagraph.AppendField("number of pages", "FieldSectionPages")
$txtWatermark.Layout = "Diagonal"
$tr1.CharacterFormat.Border.BorderType = "DashDotStroker"
$stri.CharacterFormat.TextBackgroundColor = "LightGray"
$document.LoadFromFile(".\Template_HtmlFile.html", "None")
$docObject.DocumentObjectType -eq "Picture"
$document.Sections[0].Paragraphs[0].InsertSectionBreak("NoBreak")
$footerParagraph.Format.HorizontalAlignment = "Right"

PowerShell Regex with csv file

I'm currently trying to match a pattern of IDs and replace with 0 or 1.
example pc0045601234 replace with 1234 the last 4 and add the 3rd digit in front "01234"
I tried the code below but the out only filled the userid column with No matching employee
$reportPath = '.\report.csv'`$reportPath = '.\report.csv'`
$csvPath = '.\output.csv'
$data = Import-Csv -Path $reportPath
$output = #()
foreach ($row in $data) {
$table = "" | Select ID,FirstName,LastName,userid
$table.ID = $row.ID
$table.FirstName = $row.FirstName
$table.LastName = $row.LastName
switch -Wildcard ($row.ID)
{
{$row.ID -match 'P\d\d\d\d\d\D\D\D'} {$table.userid = "Contractor"; continue}
{$row.ID -match 'SEC\d\d\d\D\D\D\D'} {$table.userid = "Contractor"; continue}
{$row.ID.StartsWith("P005700477")} {$table.userid = $row.ID -replace "P005700477","0477"; continue}
{$row.ID.StartsWith("P00570")} {$table.userid = $row.ID -replace "P00570","0"; continue}
default {$table.userid = "No Matching Employee"}
}
$output += $table
}
$output | Export-csv -NoTypeInformation -Path $csvPath
Here are three different ways to achieve the desired result. The first two use the same technique, just written in a different way.
First we put the sample data in a variable as a multiline string array. This is the equivalent as $text = Get-Content $somefile
$text = #'
PC05601234
PC15601234
'# -split [environment]::NewLine
Option 1 # convert to character array, select the 3rd and last 4 digits.
$text | foreach {-join ($_.ToChararray()| select -Skip 2 -First 1 -Last 4)}
Option 2 # same as above, requiring an extra -join to avoid spaces.
$text | foreach {(-join $_.ToChararray()| foreach{$_[2]+(-join $_[-4..-1])})}
Option 3 # my preference, regex. Capture the desired digits and replace the entire string with those two captured values.
$text -replace '^\D+(?!=\d)(\d)\w+([\d]{4}$)','$1$2'
All of these output
01234
11234
Further testing with different char/digit combinations and lengths.
$text = #'
PC05601234
PC15601234
PC0ABC124321
PC1DE4321
PC0A5678
PC1ABCD215678
'# -split [environment]::NewLine
Running the new sample data through each option all produce this output
01234
11234
04321
14321
05678
15678

Loop through a text file and Extract a set of 100 IP's from a text file and output to separate text files

I have a text file that contains around 900 IP's. I need to create batch of 100 IP's from that file and output them into new files. That would create around 9 text files.
Our API only allows to POST 100 IP's at a time.
Could you please help me out here?
Below is the format of the text file
10.86.50.55,10.190.206.20,10.190.49.31,10.190.50.117,10.86.50.57,10.190.49.216,10.190.50.120,10.190.200.27,10.86.50.58,10.86.50.94,10.190.38.181,10.190.50.119,10.86.50.53,10.190.50.167,10.190.49.30,10.190.49.89,10.190.50.115,10.86.50.54,10.86.50.56,10.86.50.59,10.190.50.210,10.190.49.20,10.190.50.172,10.190.49.21,10.86.49.18,10.190.50.173,10.86.49.49,10.190.50.171,10.190.50.174,10.86.49.63,10.190.50.175,10.13.12.200,10.190.49.27,10.190.49.19,10.86.49.29,10.13.12.201,10.86.49.28,10.190.49.62,10.86.50.147,10.86.49.24,10.86.50.146,10.190.50.182,10.190.50.25,10.190.38.252,10.190.50.57,10.190.50.54,10.86.50.78,10.190.50.23,10.190.49.8,10.86.50.80,10.190.50.53,10.190.49.229,10.190.50.58,10.190.50.130,10.190.50.22,10.86.52.22,10.19.68.61,10.41.43.130,10.190.50.56,10.190.50.123,10.190.49.55,10.190.49.66,10.190.49.68,10.190.50.86,10.86.49.113,10.86.49.114,10.86.49.101,10.190.50.150,10.190.49.184,10.190.50.152,10.190.50.151,10.86.49.43,10.190.192.25,10.190.192.23,10.190.49.115,10.86.49.44,10.190.38.149,10.190.38.151,10.190.38.150,10.190.38.152,10.190.38.145,10.190.38.141,10.190.38.148,10.190.38.142,10.190.38.144,10.190.38.147,10.190.38.143,10.190.38.146,10.190.192.26,10.190.38.251,10.190.49.105,10.190.49.110,10.190.49.137,10.190.49.242,10.190.50.221,10.86.50.72,10.86.49.16,10.86.49.15,10.190.49.112,10.86.49.32,10.86.49.11,10.190.49.150,10.190.49.159,10.190.49.206,10.86.52.28,10.190.49.151,10.190.49.207,10.86.49.19,10.190.38.103,10.190.38.101,10.190.38.116,10.190.38.120,10.190.38.102,10.190.38.123,10.190.38.140,10.190.198.50,10.190.38.109,10.190.38.108,10.190.38.111,10.190.38.112,10.190.38.113,10.190.38.114,10.190.49.152,10.190.50.43,10.86.49.23,10.86.49.205,10.86.49.220,10.190.50.230,10.190.192.238,10.190.192.237,10.190.192.239,10.190.50.7,10.190.50.10,10.86.50.86,10.190.38.125,10.190.38.127,10.190.38.126,10.190.50.227,10.190.50.149,10.86.49.59,10.190.49.158,10.190.49.157,10.190.44.11,10.190.38.124,10.190.50.153,10.190.49.40,10.190.192.235,10.190.192.236,10.190.50.241,10.190.50.240,10.86.46.8,10.190.38.234,10.190.38.233,10.86.50.163,10.86.50.180,10.86.50.164,10.190.49.245,10.190.49.244,10.190.192.244,10.190.38.130,10.86.49.142,10.86.49.102,10.86.49.141,10.86.49.67,10.190.50.206,10.190.192.243,10.190.192.241
I tried looking online to come up with a bit of working code but can't really think what would best work in this situation
$IP = 'H:\IP.txt'
$re = '\d*.\d*.\d*.\d*,'
Select-String -Path $IP -Pattern $re -AllMatches |
Select-Object -Expand Matches |
ForEach-Object {
$Out = 'C:\path\to\out.txt' -f | Set-Content $clientlog
}
This will do what you are after
$bulkIP = (get-content H:\IP.txt) -split ','
$i = 0
# Created loop
Do{
# Completed an action every 100 counts (including 0)
If(0 -eq $i % 100) {
# If the array is a valid entry. Removing this will usually end up creating an empty junk file called -1 or something
If($bulkIP[$i]) {
# outputs 100 lines into a folder with the starting index as the name.
# Eg. The first 1-100, the file would be called 1.txt. 501-600 would be called 501.txt etc
$bulkIP[$($i)..$($i+99)] | Out-File "C:\path\to\$($bulkip.IndexOf($bulkip[$($i)+1])).txt"
}
}
$i++
}While($i -le 1000)
what this does ...
calculates the number of batches
calcs the start & end index of each batch
creates a range from the above
creates a PSCustomObject to hold each batch
creates an array slice from the range
sends that out to the collection $Var
shows what is in the collection & in the 1st batch from that collection
here's the code ...
# fake reading in a raw text file
# in real life, use Get-Content -Raw
$InStuff = #'
10.86.50.55,10.190.206.20,10.190.49.31,10.190.50.117,10.86.50.57,10.190.49.216,10.190.50.120,10.190.200.27,10.86.50.58,10.86.50.94,10.190.38.181,10.190.50.119,10.86.50.53,10.190.50.167,10.190.49.30,10.190.49.89,10.190.50.115,10.86.50.54,10.86.50.56,10.86.50.59,10.190.50.210,10.190.49.20,10.190.50.172,10.190.49.21,10.86.49.18,10.190.50.173,10.86.49.49,10.190.50.171,10.190.50.174,10.86.49.63,10.190.50.175,10.13.12.200,10.190.49.27,10.190.49.19,10.86.49.29,10.13.12.201,10.86.49.28,10.190.49.62,10.86.50.147,10.86.49.24,10.86.50.146,10.190.50.182,10.190.50.25,10.190.38.252,10.190.50.57,10.190.50.54,10.86.50.78,10.190.50.23,10.190.49.8,10.86.50.80,10.190.50.53,10.190.49.229,10.190.50.58,10.190.50.130,10.190.50.22,10.86.52.22,10.19.68.61,10.41.43.130,10.190.50.56,10.190.50.123,10.190.49.55,10.190.49.66,10.190.49.68,10.190.50.86,10.86.49.113,10.86.49.114,10.86.49.101,10.190.50.150,10.190.49.184,10.190.50.152,10.190.50.151,10.86.49.43,10.190.192.25,10.190.192.23,10.190.49.115,10.86.49.44,10.190.38.149,10.190.38.151,10.190.38.150,10.190.38.152,10.190.38.145,10.190.38.141,10.190.38.148,10.190.38.142,10.190.38.144,10.190.38.147,10.190.38.143,10.190.38.146,10.190.192.26,10.190.38.251,10.190.49.105,10.190.49.110,10.190.49.137,10.190.49.242,10.190.50.221,10.86.50.72,10.86.49.16,10.86.49.15,10.190.49.112,10.86.49.32,10.86.49.11,10.190.49.150,10.190.49.159,10.190.49.206,10.86.52.28,10.190.49.151,10.190.49.207,10.86.49.19,10.190.38.103,10.190.38.101,10.190.38.116,10.190.38.120,10.190.38.102,10.190.38.123,10.190.38.140,10.190.198.50,10.190.38.109,10.190.38.108,10.190.38.111,10.190.38.112,10.190.38.113,10.190.38.114,10.190.49.152,10.190.50.43,10.86.49.23,10.86.49.205,10.86.49.220,10.190.50.230,10.190.192.238,10.190.192.237,10.190.192.239,10.190.50.7,10.190.50.10,10.86.50.86,10.190.38.125,10.190.38.127,10.190.38.126,10.190.50.227,10.190.50.149,10.86.49.59,10.190.49.158,10.190.49.157,10.190.44.11,10.190.38.124,10.190.50.153,10.190.49.40,10.190.192.235,10.190.192.236,10.190.50.241,10.190.50.240,10.86.46.8,10.190.38.234,10.190.38.233,10.86.50.163,10.86.50.180,10.86.50.164,10.190.49.245,10.190.49.244,10.190.192.244,10.190.38.130,10.86.49.142,10.86.49.102,10.86.49.141,10.86.49.67,10.190.50.206,10.190.192.243,10.190.192.241
'#
$SplitInStuff = $InStuff.Split(',')
$BatchSize = 25
$BatchCount = [math]::Truncate($SplitInStuff.Count / $BatchSize) + 1
$Start = $End = 0
$Result = foreach ($BC_Item in 1..$BatchCount)
{
$Start = $End
if ($BC_Item -eq 1)
{
$End = $Start + $BatchSize - 1
}
else
{
$End = $Start + $BatchSize
}
$Range = $Start..$End
[PSCustomObject]#{
IP_List = $SplitInStuff[$Range]
}
}
$Result
'=' * 20
$Result[0]
'=' * 20
$Result[0].IP_List.Count
'=' * 20
$Result[0].IP_List
screen output ...
IP_List
-------
{10.86.50.55, 10.190.206.20, 10.190.49.31, 10.190.50.117...}
{10.86.49.18, 10.190.50.173, 10.86.49.49, 10.190.50.171...}
{10.86.50.80, 10.190.50.53, 10.190.49.229, 10.190.50.58...}
{10.190.49.115, 10.86.49.44, 10.190.38.149, 10.190.38.151...}
{10.86.49.32, 10.86.49.11, 10.190.49.150, 10.190.49.159...}
{10.86.49.23, 10.86.49.205, 10.86.49.220, 10.190.50.230...}
{10.190.50.240, 10.86.46.8, 10.190.38.234, 10.190.38.233...}
====================
{10.86.50.55, 10.190.206.20, 10.190.49.31, 10.190.50.117...}
====================
25
====================
10.86.50.55
10.190.206.20
10.190.49.31
10.190.50.117
10.86.50.57
10.190.49.216
10.190.50.120
10.190.200.27
10.86.50.58
10.86.50.94
10.190.38.181
10.190.50.119
10.86.50.53
10.190.50.167
10.190.49.30
10.190.49.89
10.190.50.115
10.86.50.54
10.86.50.56
10.86.50.59
10.190.50.210
10.190.49.20
10.190.50.172
10.190.49.21
10.86.49.18
try this
$cpt=0
$Rang=1
#remove old file
Get-ChildItem "H:\FileIP_*.txt" -file | Remove-Item -Force
(Get-Content "H:\IP.txt") -split ',' | %{
if (!($cpt++ % 100)) {$FileResult="H:\FileIP_{0:D3}.txt" -f $Rang++} # build filename if cpt divisile by 100
$_ | Out-File $FileResult -Append
}

Powershell - Regex - Fixed width file - Escape Characters

While reading a fixed width file like this:
ABC 7112123207/24/16Smith Timpson Head Coach 412-222-0000 00011848660 ELl CAAN HIGH SCHOOL 325 N Peal AVE. Smith Timpson Head Coach COLORADO CITY AZ 86021 01 FALL MALE 07/29/16EQ15031 1977904 BUDDY'S ALL STARS INC. BUDDY ALL STARS N V12V70R16 1.00V12V70R16
I wish to escape the single whitespace, / and the apostrophe.
I tried my regex in Powershell like this:
$Line | Select-String -Pattern "^(.*)[a-zA-Z0-9?\s?]" -AllMatches
I need the match values to read as:
ABC
12345607/24/16Joe (this split into three: 123456,07/24/16,Joe)
Smith
Head Trainer
Buddy's Box
I'm trying to add the slices to a csv assigning each one to a header. For instance:
$csh.USER_GROUP = $line.Substring(0,10).Trim()
$csh.ORDER_NUMBER = $line.Substring(10,8).Trim()
$csh.ORDER_ENTRY_DATE=$line.Substring(18,8).Trim()
$csh.CONTACT_FIRST=$line.Substring(26,35).Trim()
$csh.CONTACT_LAST=$line.Substring(61,35).Trim()
$csh.CONTACT_TITLE=$line.Substring(96,35).Trim()
$csh.CONTACT_EMAIL= $line.Substring(131,35).Trim()
$csh.CONTACT_PHONE=$line.Substring(166,20).Trim()
$csh.SCHOOL_ID=$line.Substring(186,15).Trim()
} | convertto-csv | select-object -skip 1 | out-file temp.csv
Now, given that there are empty spaces and repeating elements, it is erring that duplicate keys are not allowed. Is there an elegant alternative?
Match using two or more spaces as a delimiter:
if ($Line -match '(\S.*?) +(.{6})(.{8})(.*?) +(.*?) +(.*?) +(.*)') {
$whatsit = $matches[1]
$index = $matches[2]
$date = $matches[3]
$name1 = $matches[4]
$name2 = $matches[5]
$position = $matches[6]
$place = $matches[7]
} else {
echo "Bad line $Line"
}

Powershell Regex date conversion

any idea why the following isnt working?
.................................................................................................................................................................................................................................................................................
$files = #'
name 14122012 text.doc
things 08092003.docx
hi v03.03 text 05062007 file.txt
hello world 31052006.ppt
names v04 12122012.xml
sdsf 29082013 dsf.php
'# -split '\n'
foreach ($File in $files) {
$file -match '(0[1-9]|[12][0-9]|3[01])(0[1-9]|1[012])(19|20)[0-9]{2}' | Out-Null
$File -replace "$(($matches).values)" , "$(get-date "$(($matches).Values)" -Format yyyyddMM)"
}
powershell output error is, for some reason its trying to add "20 12 14" to the string for conversion :S
Get-Date : Cannot bind parameter 'Date'. Cannot convert value "20 12 14 14122012" to type "System.DateTime". Error: "String was not recognized as a valid DateTime."
At line:13 char:9
+ get-date <<<< "$(($matches).Values)" -Format yyyyddMM
+ CategoryInfo : InvalidArgument: (:) [Get-Date], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.GetDateCommand
and
$files = #'
11.12.2012
11.12.12
15 12 2013
5 06 2013
'# -split '\n'
foreach ($File in $files) {
$file -match '\d{2}\.\d{2}\.\d{2,4}' | Out-Null
$file -match '(0[1-9]|[12]\d|3[01])\s\d{2}\s\d{2,4}'| Out-Null
$File -replace "$(($matches).values)" , "$(get-date "$(($matches).Values)" -Format yyyyMMdd)"
}
15 12 2013
Get-Date : Cannot bind parameter 'Date'. Cannot convert value "15 15 12 2013" to type "System.DateTime". Error: "String was not recognized as a valid DateTime."
At line:13 char:9
+ get-date <<<< "$(($matches).Values)" -Format yyyyMMdd
+ CategoryInfo : InvalidArgument: (:) [Get-Date], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.GetDateCommand
5 06 2013
Get-Date : Cannot bind parameter 'Date'. Cannot convert value "15 15 12 2013" to type "System.DateTime". Error: "String was not recognized as a valid DateTime."
At line:13 char:9
+ get-date <<<< "$(($matches).Values)" -Format yyyyMMdd
+ CategoryInfo : InvalidArgument: (:) [Get-Date], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.GetDateCommand
It's doing what it's supposed to do. $matches is a hash table of the the base capture (0) and each capture group:
$text = 'name 14122012 text.doc'
$regex = $file -match '(0[1-9]|[12][0-9]|3[01])(0[1-9]|1[012])(19|20)[0-9]{2}' | Out-Null
$matches
Name Value
---- -----
3 2013
2 08
1 29
0 29082013
When you ouput the collection of values as a string, it's going to space separate them:
"$(($matches).values)"
2013 08 29 29082013
That's the normal behaviour for any collection that's converted to a string. You can change the separator character from the default space by changing the Output Field Separator ($OFS)
$OFS = ';'
"$(($matches).values)"
2013;08;29;29082013
That being said, you really don't need to jump through the datetime conversion hoops. You have all the data you need already:
$files = #'
name 14122012 text.doc
things 08092003.docx
hi v03.03 text 05062007 file.txt
hello world 31052006.ppt
names v04 12122012.xml
sdsf 29082013 dsf.php
'# -split '\n'
foreach ($File in $files) {
$file -match '(0[1-9]|[12][0-9]|3[01])(0[1-9]|1[012])((?:19|20)[0-9]{2})' | Out-Null
$File -replace "$($matches[0])" , ($matches[3,2,1] -join '')
}
name 20121214 text.doc
things 20030908.docx
hi v03.03 text 20070605 file.txt
hello world 20060531.ppt
names v04 20121212.xml
sdsf 20130829 dsf.php
It just took a minor re-factoring of the regex to capture all of the year digits, then arrange the captures in the right order and join them together.
Your first problem is that you weren't capturing the entire year (only the first 2 digits), so you need to move the group capture bracket:
$file -match '(0[1-9]|[12][0-9]|3[01])(0[1-9]|1[012])(19|20[0-9]{2})'
Also, $matches returns an array that contains the entire matched string in the first element, followed by an element for each captured group.
For example:
"name 14122012 text.doc" -match '(0[1-9]|[12][0-9]|3[01])(0[1-9]|1[012])(19|20[0-9]{2})'
$matches
Name Value
---- -----
3 2012
2 12
1 14
0 14122012
So you have to recombine the string in a format the get-date will like. In my locale, it would look like this:
$matches[2,1,3] -join " "
12 14 2012
If your locale needs the day of month first, then:
$matches[1..3] -join " "
14 12 2012
which then gives:
$File -replace "$($matches[0])" , "$(get-date $($matches[2,1,3] -join ' ') -Format yyyyddMM)"
for your second line.