Powershell 根据文本中的字符串重命名文本文件 --> 更简洁的脚本方式?

Powershell rename text files based on strings in text --> More concise way for script?

我正在尝试使用帐号和对账单日期重命名 MT940 格式的银行对账单。

语句包含以下(示例):

    :20:
    :25:MHCBNL2AXXX/**0364525123**
    :28C:27/
    :60F:C200207EUR100000,00
    :61:2012311231D0000,1NMSCTOPF1234567890SDD TOPF1234567890
    :86:FR1234567890ARVAL FRANCE
    :62F:C**200207**EUR100000,00

我结合一些例子写了下面的powershell脚本,但是看起来有点长。 问题:这个脚本有没有简洁的写法?

 $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"
}

您可以通过以下方式获得类似的效果:

$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)
}
  • 通过使用 foreach 循环来迭代集合中的对象,而不是 for (in-range) 循环,您可以获得一些美学上的好处,比如能够轻松访问对象的属性干净地放在集合中。
    • 例如,不是通过调用 Get-Item $filename 来获取文件的对象实例来仅获取其扩展名,而是通过使用 foreach 循环来简化它,并且当前可迭代对象仍然是一个对象System.IO.FileSystemInfo.FileInfo 个。因此我们可以通过访问当前的可迭代对象 $File.extension.
    • 来获取它的扩展名
  • 您使用 Get-Content 多次读取一个文件,而您只需要为每个文件执行一次。
  • 在我看来,使用 .NET Match() method of the Regex class 比使用 -match 运算符更干净,但这是个人喜好。
    • 我确实尝试使用 Matches() 方法,因此我可以在一次调用中传递两个正则表达式模式(在管道 | 上拆分),但由于某种原因,在两个组中返回,而不是两种模式都匹配;一组包含 'Account' 的匹配项,而 'StatementDate' 没有匹配项,另一组则相反。