Importing CSV values with custom number formatting - powershell

I have a csv file with a timestamp column that has a custom number formatting in this format mm:ss.0.
I am trying to change that custom number formatting to h:mm:ss AM/PM, preferably during the Import-CSV command, but it doesn't have to be.
For example, 42:00.5 should be 12:42:00 AM.
Most of the examples I've seen had dates and times and could easily be converted using ToString and Get-Date but I couldn't get those examples working with just a time stamp.
Here's a few examples of what I've tried:
Import-Csv foo.csv |
Select *,#{label = 'timestamp';expression={get-date $_.Date -f 'h:mm:ss tt'}} -ExcludeProperty timestamp |
Export-Csv -NoTypeInformation foo2.cs
Import-Csv foo.csv |
Select-Object #{Name = 'timestamp'; Expression = { '{h:mm:ss tt}' -f [datetime]$_.'timestamp' }}, * -ExcludeProperty 'timestamp' |
Export-Csv -NoTypeInformation foo2.csv
What am I missing?
This is where I would go in Excel to change the custom number format. The selected is what the current number format is and the highlighted is what I need.

Related

Powershell - Formatting column as date

I am importing a CSV which has 5 "columns". One of them is a date and time. The 3rd party software that is reading this column, then does not sort the date well.
IE: (4/8/2022 1:24:08 PM) will sort above (4/13/2022 8:51:52 AM)
Even though 4/13 is after 4/8 it will not sort it properly. I would like to add a leading zero in front of the month and date with powershell. I did do some searching but nothing seems to make sense to me, I am not a HUGE programmer.
Thanks for any help!
This is what I am currently doing. I am using unique to remove duplicate rows (this is needed for what I am doing).
$FinalSessions = Import-Csv -Path "C:\Windows\AdminArsenal\UserSessions.csv" | Sort-Object * -Unique
$FinalSessions | Export-Csv -Path "C:\Windows\AdminArsenal\UserSessions.csv" -NoTypeInformation
$FinalSessions
You can use Get-Date to actually get a datetime object and then reformat it.
It would look something like this:
$FinalSessions = Import-Csv -Path "C:\Windows\AdminArsenal\UserSessions.csv"| Sort-Object * -Unique
$FinalSessions | % { $_.DateColumn = Get-Date $_.DateColumn -Format "MM/dd/yyyy hh:mm:ss tt" }
$FinalSessions | Export-Csv -Path
"C:\Windows\AdminArsenal\UserSessions.csv" -NoTypeInformation
$FinalSessions
Just replace "DateColumn" with the name of your column
Assuming that the column that contains the date-time string is named Date (adjust as needed):
Import-Csv -Path C:\Windows\AdminArsenal\UserSessions.csv |
ForEach-Object { $_.Date = ([datetime] $_.Date).ToString('s') } |
Sort-Object * -Unique -OutVariable finalSessions |
Export-Csv -Path C:\Windows\AdminArsenal\UserSessions.csv -NoTypeInformation
$finalSessions
Note that the s format specifier (in ISO 8601 format) is used to reformat the date-time strings, as that results in a string whose lexical sorting reliably indicates chronological order, across year boundaries; e.g. 2022-05-05T17:52:47

Need 3 digits in column in a CSV-file

I have a script that extracts data from an XML file and put this into an CSV file with 2 columns.
The file looks like this:
Name, Count
1,34
3,55
15,66
103,99
etc.
So far so good...
My problem is that the program that reads the CSV-file always expect 3 digits in the column "Name".
So the CSV-file need to look like this:
Name, Count
001,34
003,55
015,66
103,99
etc.
How can I do this formatting using "Export-CSV"?
Please help I'm stuck here..
There are several ways to apply the changes to the csv file.
Read/Import to a variable, change name, Export-Csv variable
$Csv = Import-Csv .\Sample.csv
$Csv | ForEach-Object{ $_.Name = $_.Name.PadLeft(3,'0') }
$Csv | Export-Csv .\NewSample.csv -NoTypeInformation
Do the same on the fly with a calculated property reusing the same header/property name.
Import-Csv .\Sample.csv |
Select-Object #{n='Name';e={$_.Name.PadLeft(3,'0')}},Count|
Export-Csv .\NewSample2.csv -NoTypeInformation
Use the -f ( format ) operator with variable
i.e.
[int] $int = 25;
"{0:D3}" -f $int
Here 3 is a number of digits and Output will be :
025

How to export to "non-standard" CSV with Powershell

I need to convert a file with this format:
2015.03.27,09:00,1.08764,1.08827,1.08535,1.08747,8941
2015.03.27,10:00,1.08745,1.08893,1.08604,1.08762,7558
to this format
2015.03.27,1.08764,1.08827,1.08535,1.08747,1
2015.03.27,1.08745,1.08893,1.08604,1.08762,1
I started with this code but can't see how to achieve the full transformation:
Import-Csv in.csv -Header Date,Time,O,H,L,C,V | Select-Object Date,O,H,L,C,V | Export-Csv -path out.csv -NoTypeInformation
(Get-Content out.csv) | % {$_ -replace '"', ""} | out-file -FilePath out.csv -Force -Encoding ascii
which outputs
Date,O,H,L,C,V
2015.03.27,1.08745,1.08893,1.08604,1.08762,8941
2015.03.27,1.08763,1.08911,1.08542,1.08901,7558
After that I need to
remove the header (I tried -NoHeader which is not recognized)
replace last column with 1.
How to do that as simply as possible (if possible without looping through each row)
Update : finally I have simplified requirement. I just need to replace last column with constant.
Ok, this could be one massive one-liner... I'm going to do line breaks at the pipes for sanity reasons though.
Import-Csv in.csv -header Date,Time,O,H,L,C,V|select * -ExcludeProperty time|
%{$_.date = [datetime]::ParseExact($_.date,"yyyy.MM.dd",$null).tostring("yyMMdd");$_}|
ConvertTo-Csv -NoTypeInformation|
select -skip 1|
%{$_ -replace '"'}|
Set-Content out.csv -encoding ascii
Basically I import the CSV, exclude the time column, convert the date column to an actual [datetime] object and then convert it back in the desired format. Then I pass the modified object (with the newly formatted date) down the pipe to ConvertTo-CSV, and skip the first line (your headers that you don't want), and then remove the quotes from it, and lastly output to file with Set-Content (faster than Out-File)
Edit: Just saw your update... to do that we'll just change the last column to 1 at the same time we modify the date column by adding $_.v=1;...
%{$_.date = [datetime]::ParseExact($_.date,"yyyy.MM.dd",$null).tostring("yyMMdd");$_.v=1;$_}|
Whole script modified:
Import-Csv in.csv -header Date,Time,O,H,L,C,V|select * -ExcludeProperty time|
%{$_.date = [datetime]::ParseExact($_.date,"yyyy.MM.dd",$null).tostring("yyMMdd");$_.v=1;$_}|
ConvertTo-Csv -NoTypeInformation|
select -skip 1|
%{$_ -replace '"'}|
Set-Content out.csv -encoding ascii
Oh, and this has the added benefit of not having to read the file in, write the file to the drive, read that file in, and then write the file to the drive again.

Format a column of dates in CSV

I'm attempting to format some dates in the first column of a CSV. I would prefer to user something like powershell as I plan to automate this task. Does anyone have any advice on the best way to change the format of the date from something like MM/DD/YYY to YYYY-MM-DD? I've tried something like this:
$date = date -f ('yyyyMMdd')
$HMDA = Import-Csv "C:\HMDA\$date.YieldTableFixed.csv"
ForEach-Object {
$HMDA.Date = [datetime]::ParseExact($HMDA.Date).ToString('YYYY-MM-DD')
} |
Export-Csv -NoTypeInformation C:\HMDA\test.csv
Unfortunately, that didn't seem to do anything but give me a parse error and I can't seem to figure out why that is. Is there a way I can say something like:
ForEach-Object{
$HMDA.A2:$HMDA.A63 = HMDA.$AC.Date.Format('YYYY-MM-DD')
}
Ok, there's some basic errors here, but that's just a matter of not knowing better I think. Now this is hard to answer accurately because you did not give us an example of the incoming date field, so if it has some strange formatting this may throw errors as PowerShell fails to recognize that a string is in fact a date.
First off, if you pipe to a ForEach loop you reference the current object with $_. Such as:
Import-Csv "C:\HMDA\$date.YieldTableFixed.csv" | ForEach-Object {
$_.Date = get-date $_.Date -f 'yyyy-MM-dd'
} | Export-Csv -NoTypeInformation C:\HMDA\test.csv
What would probably be simpler, as I recently learned from somebody else here on SO, would be to use Select, create the updated property on the fly, and then exclude the original property, effectively replacing it with the new one. Something like this:
Import-Csv "C:\HMDA\$date.YieldTableFixed.csv" |
Select *,#{label = 'Date';expression={get-date $_.Date -f 'yyyy-MM-dd'}} -ExcludeProperty Date |
Export-Csv -NoTypeInformation C:\HMDA\test.csv
ParseExact() expects 3 parameters: the date string, a format string, and a format provider (which may be $null). Also, your output format string is incorrect (the year and day format specifiers need to be lowercase), and ForEach-Object reads from a pipeline.
Change this:
$HMDA = Import-Csv "C:\HMDA\$date.YieldTableFixed.csv"
ForEach-Object {
$HMDA.Date = [datetime]::ParseExact($HMDA.Date).ToString('YYYY-MM-DD')
} |
Export-Csv -NoTypeInformation C:\HMDA\test.csv
into this:
Import-Csv 'C:\HMDA\$date.YieldTableFixed.csv' | ForEach-Object {
$_.Date = [DateTime]::ParseExact($_.Date, '*M\/dd\/yyyy', $null).ToString('yyyy-MM-dd')
$_
} | Export-Csv -NoTypeInformation 'C:\HMDA\test.csv'

Convert date format in CSV using PowerShell

I have two CSV file with 50 column and more than 10K row. There is a column having date-time value. In some records it is 01/18/2013 18:16:32 and some records is 16/01/2014 17:32.
What I want to convert the column data like this: 01/18/2013 18:16. I want to remove seconds value. I want to do it by PowerShell script.
Sample data:
10/1/2014 13:18
10/1/2014 13:21
15/01/2014 12:03:19
15/01/2014 17:39:27
15/01/2014 18:29:44
17/01/2014 13:33:59
Since you're not going to convert to a sane date format anyway, you can just do a regex replace of that column:
Import-Csv foo.csv |
ForEach-Object {
$_.Date = $_.Date -replace '(\d+:\d+):\d+', '$1'
} |
Export-Csv -NoTypeInformation foo-new.csv
You could also go the route of using date parsing, but that's probably a bit slower:
Import-Csv foo.csv |
ForEach-Object {
$_.Date = [datetime]::Parse($_.Date).ToString('MM/dd/yyyy HH:mm')
} |
Export-Csv -NoTypeInformation foo-new.csv
If you're sure that there are no other timestamps or anything that could look like it elsewhere, you can also just replace everything that looks like it without even parsing as CSV:
$csv = Get-Content foo.csv -ReadCount 0
$csv = $csv -replace '(\d{2}/\d{2}/\d{4} \d{2}:\d{2}):\d{2}', '$1'
$csv | Out-File foo-new.csv