我的 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.txt
get-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 中将通配符递归应用于整个项目树,请添加参数
-recurse
:get-childitem c:\music\*.mp3 -recurse
或者更明确地说:
get-childitem c:\music\ -filter *.mp3 -recurse
-
标准别名对于 Foreach 对象:'
%
' 符号,ForEach -
钥匙
strSeparator
用于分割每个字符串的字符,默认为空格(空格/换行符/制表符) -
默认情况下
trim()
将删除前导和尾随空格以及前导和尾随换行符。