Powershell replace operator is bringing across array artifacts - powershell

I need to get a date from a cell in a CSV file, then remove the '20' from the year.
I have the below code:
$rateID="C:\Folder\Path\RateIDTable.csv"
$date = Import-CSV $rateid | select -first 1 -Property date
$date = $date -replace '[20]',''
write-output $date
Output looks like this though:
What I need is '17/01/18' but it adds the whole variable and removes the zero that I need.
Any tips on this one?
Thanks!

Either you convert the "string date" to a datetime object and format it accordingly or you change the regex pattern you use in your -replace operator like this
$date = $date -replace '/20','/'
The square brackets in regex define a charachter class. So with '[20]' the regex matches ALL two's and ALL zero's in the string.

OK, figured it out. bit of a messy way to do it, but here is my code:
$rateID="C:\Folder\Path\RateIDTable.csv"
$datestr="C:\folder\path\fdate.txt"
$date = Import-CSV $rateid | select -first 1 -Property date
$fdate = $date | foreach-object {$_.date} | set-content $datestr
$fdate = (get-content $datestr) -replace ('20','')
write-output $fdate
And my output is this:
17/01/18
Thanks to all those who helped!

Once you have your $date object, format it as such:
$date = $date.ToString("dd/MM/yy")
Adding more clarification since my answer did not seem to work for you. I assumed a few things, that I can see did not work for you.
$date1 = [datetime]::Now
$date2 = [datetime]::Parse("01/18/2018")
$mydate = "01/19/2018"
$date3 = [datetime]::Parse($mydate)
$date1.ToString("dd/MM/yy")
$date2.ToString("dd/MM/yy")
$date3.ToString("dd/MM/yy")
Your $date was a string, not a Date, so yes, to use ToString, it would need to be a DateTime object which you can see a few ways to create above. Hope this helps you in future efforts.
Note, you may need to change the strings depending on your locale so they parse correctly, but hopefully the above makes sense...

Related

Converting CSV data to datetime format

I'm still learning Powershell and in order to complete an assignment I need to convert written data in CSV files to a powershell accepted datetime format.
The dates in the CSV format are written as: 1-1-2014.
In order to convert them I found out (through a bit of brute force) that I can use the following code:
$Files = gci $Source\*.csv
$Data = Import-CSV $Files -Delimiter ";"
$Data | ForEach-Object { $_.Time = $_.Time -as [datetime]
$_
}
However, it would seem to me that this should work as well when written as follows:
$Data | ForEach-Object { $_.Time = $_.Time -as [datetime] $_ }
When I run it like that it returns a bunch of errors.
The $_ after [datetime] I also only added because a colleague used that in his functions, I don't really understand why it has to be put there, and why it needs to be put on a new line. Could anyone explain? If there is a different/better way to convert CSV data to a datetime format I'd be interested in hearing those as well, thanks in advance!
The first (multi-line) version works because PowerShell interprets a line-break after a complete statement as a terminator - it knows that $_ is a separate statement from $_.Time = $_.Time -as [datetime].
To place multiple separate statements on a single line, you'll have to use a semicolon ; to separate them:
$Data | ForEach-Object { $_.Time = $_.Time -as [datetime]; $_ }

Exclude parameters taken from XML by regular expression (regex)

I have a parameter in XML files with a mask:
<id>ALL2-20210301-XXXXXX-XXXXX_X</id>
where ALL2 is always the same parameter, 20210301 is a date so changing every day, and XXXXXX-XXXXX_X is a variable parameter.
I want to parse XML and get 20210304 value (or other date) with regex - I don't need any other parameter from . How should regular expression value looks like?
code is:
[xml]$xml = Get-Content c:\buy\buy.xml
$date= $xml.buy.id[0]
if ($date -match "regex?") {
$date = $matches[0];
}
You don't need regex, you can just split on '-' and take the second element, so for example:
$result = ($date -split '-')[1]
It is likely faster than regex too (haven't measured).
Several alternative approaches
$date = 'ALL2-20210301-XXXXXX-XXXXX_X'
$date.Split('-')[1]
$date -split '-' | Select-Object -Index 1
$date -replace '^.+?-|-.+$'
$date -replace '.+(\d{8}).+','$1'
[regex]::Match($date,'\d{8}').Value
if($date -match '\d{8}'){$matches.0}

Powershell Select-String

I need your help with PowerShell.
I need Select-String with fixed Date (in variable). & Set-Content to result.txt
Example: $Date = "01.07.2020"
But also i need select string with date which lower than i written in variable.
My code: Get-Content -Path log.txt | Select-String "?????" | Set-Content $result.txt
In log.txt i have many strings like " Creation date 01.07.2020 " ; " Creation date 01.06.2020 "
123.txt
Creation date 01.07.2020
Creation date 02.05.2020
Creation date 01.06.2020
Creation date 28.08.2020
Example script
$file = "C:\Users\userprofile\Desktop\test\123.txt"
$regexpattern = "\d{2}\.\d{2}\.\d{4}"
$content = Get-Content $file | Where-object { $_ -match $regexpattern}
foreach($line in $content){
$line.Substring(13,11)
}
I used regex to find the lines you are wanting to output. We get the content only if it matches our regex, then for each line we found, I'm using substring to pull the date out. You could also put together a regex for this if you wanted to. Since we know the lines have the same number of characters it's safe to use the substring function.
If you want that output to a file, simply find $line.Substring(13,11) and then add this after it | Out-file "C:\Users\userprofile\desktop\test\output.txt" -append.

Finding value in a CSV file and comparing with today's date

I'm trying to get a value from a CSV file.
If today's date = DateInCSVFile give the "key" value.
Keys.csv
Guest,Key
1-Jun,OIOMY-ZFILZ
2-Jun,LSSJC-PDEUL
3-Jun,MQNVJ-TETLV
4-Jun,HCJIJ-ECVPY
5-Jun,SPACR-AJSLU
6-Jun,MEURS-UQTVX
Code:
$today = Get-Date -format dd-MMM
$keys = import-csv c:\office\keys.csv -Header #(1..2)
$data = $keys | ? { $_.1 -match $today}
Write-Host $data.2
I tried the foreach and if commands. Nothing worked.
I can think of a couple of options. If you want something quick and dirty, try:
$stuff = Import-Csv -Path .\stuff.csv
foreach ($thing in $stuff) {
if ( $thing.Guest -eq $(Get-date -Format 'd-MMM') ) {
Write-Output $thing.Key
}
}
I import the CSV file's contents to a variable. I iterate over each line. If the day in Guest matches the current day, I output the key
The only problem with your code is your date format, dd-MMM, as LotPings observes:
It creates 0-left-padded numbers for single-digit days such as 6, whereas the dates in the CSV have no such padding.
Thus, changing Get-Date -format dd-MMM to Get-Date -format d-MMM (just d instead of dd) should fix your problem.
However, given that you're reading the entire file into memory anyway, you can optimize the command to (PSv4+):
$today = Get-Date -Format d-MMM
(Import-Csv c:\office\keys.csv).Where({ $_.Guest -eq $today }).Key
Also note that the purpose of -match is to perform regular-expression-based matching, not (case-insensitive) string equality; use -eq for the latter.

Powershell change date format based on regex

I am trying to use a regex to find dates in a csv file and change the formatting because there are over 200 columns in this csv; manual column mapping for each date is not possible.
what I had previously was the following
$sf = '\\path\dept\Extracts\Date_Modified.csv'
$regex = "\d{1,2}/\d{1,2}/\d{4}"
(Get-Content $sf) |
Foreach-Object {$_ -replace $regex, (get-date -f "yyyy-MM-dd") } |
Set-Content $sf
that works fine if I want to replace all the dates with the current date, but that wasn't my goal. my goal is to recognize human entry type dates (mm/dd/yyyy) and change them to yyyy-mm-dd that the database table is expecting when I load the csv.
how can I modify this? or is there a better way to recognize date formats and change the format?
The answer: use capture groups. I don't know why you wouldn't be able to assign the regex to a variable before use (as I have done many times):
$sf = '\\path\dept\Extracts\Date_Modified.csv'
$regex = '(\d{1,2})\/(\d{1,2})\/(\d{4})'
#(Get-Content -Path $sf) |
ForEach-Object { $_ -replace $regex, '$3-$1-$2' } |
Set-Content -Path $sf
Of special note, use single-quotes in the replace statement so you don't end up trying to interpolate $1 into a (presumably null) variable.