I am trying to rename bankstatements in MT940-format using the account number and the statement date.
The statements contain the following (example):
:20:
:25:MHCBNL2AXXX/**0364525123**
:28C:27/
:60F:C200207EUR100000,00
:61:2012311231D0000,1NMSCTOPF1234567890SDD TOPF1234567890
:86:FR1234567890ARVAL FRANCE
:62F:C**200207**EUR100000,00
I have written the following powershell script by combining some examples but it seems quite long for the purpose. Question: Is there a concise way to write this script?
$files = Get-ChildItem "C:\Dropbox\Temp\Gerard\test\*" -Include *.txt, *.ged
for ($i=0; $i -lt $files.Count; $i )
{
$filename = $files[$i].FullName
#Rename the file based on strings in the file
$Account = (Get-Content -Raw -Path $fileName)
$Account -match ":25:. (\d{10})"
$Account = $matches[1]
$StatementDate = (Get-Content -Raw -Path $fileName)
$StatementDate -match ":62F:C(?<content>.*)EUR"
$StatementDate = $matches['content']
$file=Get-Item $filename
$file.Basename
$extension=$file.Extension
Rename-Item -Path $filename -NewName "$StatementDate-$Account$extension"
}
CodePudding user response:
You could have achieved similar with the below:
$Files = Get-ChildItem '/Users/acc/Downloads/bank/*' -Include '*.txt', '*.ged'
foreach ($File in $Files) {
$Content = Get-Content -Path $File -Raw
$Account = [Regex]::Match($Content, ':25:. \*{2}(?<Account>\d{10})\*{2}').Groups['Account'].Value
$StatementDate = [Regex]::Match($Content, ':62F:C\*{2}(?<StatementDate>\d )\*{2}EUR').Groups['StatementDate'].Value
Rename-Item -Path $File -NewName ('{0}-{1}{2}' -f $StatementDate, $Account, $File.Extension)
}
- By using the
foreachloop to iterate over objects in a collection, instead of afor(in-range) loop, you gain some aesthetic benefits like being able to easily access object's properties cleanly in the collection.- For example, instead of getting an object instance of your file by calling
Get-Item $filenameto only get its extension, it is simplified by using theforeachloop and the current iterable is still an object ofSystem.IO.FileSystemInfo.FileInfo. Therefore we can get its extension by accessing the current iterable$File.extension.
- For example, instead of getting an object instance of your file by calling
- You were reading from a file multiple times with
Get-Contentwhere you only needed to do this once for each file. - In my opinion, using the .NET
Match()method of the Regex class is cleaner than using the-matchoperator, but this is personal preference.- I did try to use the
Matches()method so I could pass both regex patterns (split on a pipe|) in one call, but for some reason, in both groups returned, not both patterns were matched; one group contained a match for 'Account' whereas it did not for 'StatementDate', and vice versa on the other group.
- I did try to use the
