I have a log file and I need to identify the lines where we have a date and replace those date format with our required format
Let take an example that we have a line in the log which looks like
³3468³AL GOWEFLY³AYSHA ABDULREHMAN³³³³1508701³1975-03-02 00:00:00.000 ³1³³³³³³³³³³2³³5³³³
I need to find this line and replace this date 1975-03-02 into1975-mar-02
Note: The length of the line and where the date will be in the line is not fixed, it can be anywhere
I am able to find the lines where we have a date using the below code now, I am unable to understand how we can replace numeric month into words.
Can someone please help me here?
$logconatins=Get-Content .\3468_3489.log
$logconatins| Select-String '(\d\d\d\d)-([1-9]|([012][0-9])|(3[01]))-([0]{0,1}[1-9]|1[012])
`
I am trying to use Get-Culture).DateTimeFormat.GetAbbreviatedMonthName to convert the value which is actually working but its seem while replacing the value with the actual value, I am getting below error
$logconatins | | Foreach-Object {$_.replace("(\d\d\d\d)-((([A-Z]|[a-z])([A-Z]|[a-z])([A-Z]|[a-z]))|([1-9]|([012][0-9])|(3[01])))-([0]{0,1}[1-9]|1[012])", $1-$((Get-Culture).DateTimeFormat.GetAbbreviatedMonthName($2)))-$3}
error:
Cannot convert value “Mar” to type “System.Int32”. Error: “Input string was not in a correct format.”
At line:1 char:204
- … 12])", $1-$((Get-Culture).DateTimeFormat.GetAbbreviatedMonthName($2)) …
-
- CategoryInfo : InvalidArgument: ( , RuntimeException
- FullyQualifiedErrorId : InvalidCastFromStringToInteger
At line:1 char:204
- … 12])", $1-$((Get-Culture).DateTimeFormat.GetAbbreviatedMonthName($2)) …
-
- CategoryInfo : InvalidArgument: ( , RuntimeException
- FullyQualifiedErrorId : InvalidCastFromStringToInteger
Here’s how I’d do it. It works well and it makes the code quite readable.
First for the demo we will set up some sample text.
$data = @'
³3468³AL GOWEFLY³AYSHA ABDULREHMAN³³³³1508701³1975-03-02 00:00:00.000 ³1³³³³³³³³³³2³³5³³³
³3AL GFLY³AYSHA ABDULREHMAN³³³³171³2010-12-12 00:22:00.000 ³1³³³³³³³³³³2³³5³³³
³3AAYSHA ABDUMAN³³³³1701³1999-01-01 12:01:51.000 aaaaabbbbbbbbb335677533q11ddddv33555555555555
'@
Now we will make a regex object of the pattern we want to match.
$regex = [regex]'(?<=\d{4}-)\d{2}(?=-)'
Next we will make a function to convert the match to the abbreviated month.
$convert = {
Param($month)
([cultureinfo]::InvariantCulture).DateTimeFormat.GetAbbreviatedMonthName($month.value)
}
Finally we will process all the lines.
$regex.Replace($data,$convert)
The output
³3468³AL GOWEFLY³AYSHA ABDULREHMAN³³³³1508701³1975-Mar-02 00:00:00.000 ³1³³³³³³³³³³2³³5³³³
³3AL GFLY³AYSHA ABDULREHMAN³³³³171³2010-Dec-12 00:22:00.000 ³1³³³³³³³³³³2³³5³³³
³3AAYSHA ABDUMAN³³³³1701³1999-Jan-01 12:01:51.000 aaaaabbbbbbbbb335677533q11ddddv33555555555555
Since it works on the entire text you don’t need to put it through a loop, this will speed it up. So you can simply read all the text (if it’s not too large for memory) with Get-Content -Raw . Here is the complete code.
$data = Get-Content $logfile -Raw
$regex = [regex]'(?<=\d{4}-)\d{2}(?=-)'
$convert = {
Param($month)
([cultureinfo]::InvariantCulture).DateTimeFormat.GetAbbreviatedMonthName($month.value)
}
$regex.Replace($data,$convert)