不同的方法

不同的方法

我的 Powershell 版本是 5.1.19041.1645

我想使用 txt 文件将音频文件从多个文件夹复制到另一个文件夹,其中 List.txt 文件中的歌曲名称与原始文件夹中的歌曲名称的结构不同。

我使用链接作为示例:
从目录中搜索并复制文件

我试过:

$files = 'C:\Users\CMG\Desktop\List.txt'
$location = 'C:\Users\CMG\Desktop\Select Dance\'
$destination = 'C:\Users\CMG\Desktop\Select Dance Copy\'

Get-ChildItem $location -Filter *.mp3 |
Foreach-Object {  
  $content = $_.Name
  $pos = $content.IndexOf("-")
  $artistPart = $content.Substring(0, $pos)
  $musicPart = $content.Substring($pos+2)

  $pos2 = $musicPart.IndexOf(".")
  $musileft = $musicPart.Substring(0, $pos2)

  If ($pos2 -lt 36) {
    $leng=$pos2
  } else {
    $leng=$pos2-($pos2-36)
  } 

  $musicNameRight = $musileft.Substring(0, $leng)  
}     
gc $files | % {
                   
    $result = gci -Recurse $location$musicNameRight $_
            
    if($result) {
        write-host -ForegroundColor Green "found $_ in $location!"
        write-host "copying $_ to $destination..."
        copy-item $result.FullName $destination\$_
    }
}

在 Foreach-Object 中,我设法从原始名称 ($location) 中消除了不同的部分,Artist Name -.mp3从 List.txt ($files) 中的名称中消除了不同的部分,但我无法让脚本使用来自变量的信息来比较文件$musicNameRight

“$files”路径包含的歌曲名称:
Good Times (Dj 'S' Bootleg CMG Dance

“$location”路径包含的歌曲名称:
Chic - Good Times (Dj 'S' Bootleg CMG Dance Re Mix).mp3

如何让脚本使用变量中名称的正确信息$musicNameRight

注意:
我定义了$musicPart.Substring(0, 36),因为 List.txt 文件中的所有歌曲名称都限制为 36 个字符。它们永远不会超过这个长度。

答案1

根据我的理解,您只需对gci变量参数值进行简单的调整即可对现有逻辑进行最小的更改。

  • 而不是使用$result = gci -Recurse $location$musicNameRight $_

  • 改用$result = gci -Recurse "$location*$_*"

在后面和前面添加一个星号,将$_作为通配符,该Get-ChildItem命令将递归返回找到的所有匹配文件的结果。同时将包括这些星号在内的连接变量括在双引号中(即"$location*$_*")。

PowerShell(选项 1)

$files = 'C:\Users\CMG\Desktop\List.txt'
$location = 'C:\Users\CMG\Desktop\Select Dance\'
$destination = 'C:\Users\CMG\Desktop\Select Dance Copy\'

Get-ChildItem $location -Filter *.mp3 | % {
    $musicNameRight = $_.Basename.Split("-")[1].Trim();
    If ($musicNameRight.Length -gt 36) {$musicNameRight = $musicNameRight.Substring(0, 36)};
    };

Get-Content $files | % {               
    $result = Get-ChildItem -Recurse "$location*$_*" 
    If($result) {
        Write-Host -ForegroundColor Green "found $_ in $location!"
        Write-Host "copying $_ to $destination..."
        Copy-Item $result.FullName -Destination $destination\$($_.Name)
    }
};

不同的方法

使用split破折号 ( -) 作为分隔符,索引[1]将提供与 相同的结果。我还认为您根本substrings不需要使用或命令。list.txtget-content

使用通配符包围$musicNameRight变量,我将$result使用移至同一foreach-object循环中,以便从那里执行条件复制。将带有变量的扩展名保留在那里作为首选目标文件名是安全的。

笔记:如果您想要的是包含名称、歌曲艺术家姓名和歌曲名称加扩展名的原始名称,请使用脚本中注释掉的copy-item条件下方的(即)。If()Copy-Item $result.FullName -Destination $destination\$_;

PowerShell(选项 2)

$location = 'C:\Users\CMG\Desktop\Select Dance\';
$destination = 'C:\Users\CMG\Desktop\Select Dance Copy\';

Get-ChildItem $location -Filter *.mp3 |
Foreach-Object {  
  $musicNameRight = "$($_.Basename.Split("-")[1])$($_.Extension)".Trim();
  
  $result = gci -Recurse "$location*$musicNameRight*";
  If ($result) {
    Write-Host -ForegroundColor Green "Found $_ in $location!";
    Write-Host "Copying $_ to $destination...";
    Copy-Item $result.FullName -Destination $destination\$musicNameRight;
    ##Copy-Item $result.FullName -Destination $destination\$_;
    };

}

支持资源

  • 获取子项

    通配符

    当列出单个文件夹(不递归)时,您可以执行 get-childitem c:\music\*.mp3与 CMD shell 不同,在 PowerShell 中,路径过滤器c:\music\*.mp3仅适用于文件而不是文件夹(或其他容器)。

    要在 PowerShell 中将通配符递归应用于整个项目树,请添加参数-recurseget-childitem c:\music\*.mp3 -recurse

    或者更明确地说:
    get-childitem c:\music\ -filter *.mp3 -recurse

  • ForEach 对象

    标准别名对于 Foreach 对象:' %' 符号,ForEach

  • 分裂()

    钥匙

    strSeparator 用于分割每个字符串的字符,默认为空格(空格/换行符/制表符)

  • 修剪()

    默认情况下trim()将删除前导和尾随空格以及前导和尾随换行符。

  • 如果()

  • String.Length 属性

  • 比较运算符

相关内容