更正错误的匹配单词以正确修复文件夹中的移动文件

时间:2016-09-17 20:18:06

标签: powershell

我使用脚本制作文件夹并将文件移动到按年份排序的相关文件夹。

我有以这种格式列出的电影+年份

rambo (1982)
rambo III (1988)
Independence Day (1996)
...

我期待这种结构:

├─1982 [folder]
│ ├─Rambo.torrent [file]
│ ├─Rambo DVD.torrent [file]
│ └─Blade Runner.torrent [file]
├─1985 [folder]
│ └─Rambo: First Blood Part II.torrent [file]
├─1988 [folder]
│ └─Rambo III.torrent [file]
├─2008 [folder]
│ └─John Rambo.torrent [file]
:

但这就是结构的实际外观:

├─2008 [folder]
│ ├─Rambo.torrent [file]
│ ├─Rambo: First Blood Part II.torrent [file]
│ ├─Rambo III.torrent
│ └─John Rambo.torrent
:

脚本正确创建文件夹并移动文件,但是以自己的方式执行。

我的脚本错误地将同一个单词中的每个.torrent 移动到同一年份文件夹中的Rambo文件名中。

SCRIPT

$movies = @()
(Get-Content C:\Path\Test4.txt) | foreach($_) {
  $properties = @{
    date = $_.Substring($_.IndexOf("(")+1, 4)
    name = $_.Substring(0, $_.IndexOf("("))
  }
  Write-Host $date
  Write-Host $name

  $movies += New-Object PSObject -Property $properties
}

$torrentFiles = dir $torrentPath

foreach ($movie in $movies) {
  $datePath = "C:\Path\$($movie.date)"
  if (-not(Test-Path $datePath)) {
    New-Item $datePath -ItemType "directory"
  }
  $words = ($movie.Name -split '\s') | ?{ $_.Length -gt 1 }
  $significant = $words.Count
  $torrentFile | Move-Item {
    $matchingWords = 0
    foreach ($word in $words) {
      if ($torrentFile.BaseName -match $word) {
        $matchingWords += 1
      }
    }
    if ($matchingWords -ge $significant) {
      $_ | Move-Item -Destination $datePath
    }
  }
}

1 个答案:

答案 0 :(得分:2)

我会使用文件的cannot borrow x as mutable more than once属性来匹配列表中的电影,在第一次运行后,您可以采用列表并添加未移动的电影。那可能比匹配单词更可靠。

因此,经过一些重构后,您的脚本可能如下所示:

BaseName

使用正则表达式:

$movieFile = 'C:\Path\Test4.txt'
$moviesDestionation = 'C:\Destination'
$moviesSource = 'C:\Path'

# parse movie list
$movies = Get-Content $movieFile | ForEach-Object {
        $regMatch = [regex]::Match($_, '(?<name>.*?)\s?\((?<year>\d+)\)$')
        [PSCustomObject]@{
            Name = $regMatch.Groups['name'].Value
            Year = $regMatch.Groups['year'].Value
        }
    }

# create folder structure
$movies | select -Unique Year | ForEach-Object { 
    md (Join-Path $moviesDestionation $_.Year)  -Force -ea 0
}

# move all files
(Get-ChildItem $moviesSource -Filter '*.torrent') | ForEach-Object {
    $matchedMovie = $movies | where Name -eq $_.BaseName 
    if ($matchedMovie)
    {
        $_ | Move-Item -Destination (Join-Path $moviesDestionation $matchedMovie.Year)
    }
}

Regular expression visualization