
[英]C# Moving Files into Folders if part of the file name matches the folder name
[英]Moving files to a folder if the folder name contains a part of the file name?
我正在编写一个脚本,将文件从源目录复制到在文件和文件夹名称中共享 10 位字符串的单个文件夹。 文件和文件夹名称不相同,但它们都将包含我尝试匹配的 10 位数字。 $num_list
包含一个电话号码列表,这些电话号码也位于文件名中的某个位置。 例子:
1234567890
1234567891
1234567892
我的目标是从我的源目录中复制类似于Inbound_1234567890.mp3
的文件,并将它们复制到目标目录中名为Person 1234567890
的文件夹中
这是我当前的脚本:
#set source and destination directory
$source = "D:\testInput\Ring\Archiver"
$destination = "D:\testOutput\Clients"
#creates .txt with all folder names
Get-ChildItem $destination | ForEach-Object { $_.Name } > $destination\num_list.txt
#removes everything but the phone number
(Get-Content $destination\num_list.txt) -replace '\D','' | Set-Content $destination\num_list.txt
#list of numbers generated from destination
$num_list = Get-Content "$destination\num_list.txt"
#for each number in num_list
foreach ($num in $num_list){
#for each file in the ring archive
foreach($file in (Get-ChildItem $source -Filter *.mp3 -Recurse)){
#if the file name is in the directory
if($num -match '\d{10}'){
Copy-Item $file.Fullname -Destination $destination -Verbose
}
}
}
我的 output 最终将文件复制到目的地,根据脚本这是正确的,但我不知道如何定位文件夹名称中包含电话号码的每个文件夹。 我尝试使用通配符创建一个新目录来指定路径,但该语法无法正常工作
if($num -match '\d{10}'){
$folder_name = $matches[0]
$new_dest = $destination\*$folder_name*
Copy-Item $file.Fullname -Destination $new_dest -Verbose
有没有办法仅根据电话号码来定位每个单独的文件夹?
谢谢您的帮助!
更新:我尝试了一种不同的方法,但我一直认为目标录制路径是 null。 我还选择尝试通过 txt 文件中的数字匹配正则表达式,因为 mp3 文件包含其他 10 位数字组合以供查看。 有关改进此逻辑的任何建议? 我知道我很近,但还很远。
#set source and destination directory
$source = "D:\testInput\Ring\Archiver"
$destination = "D:\testOutput\Clients"
Get-ChildItem $destination | ForEach-Object { $_.Name } > $destination\num_list.txt
(Get-Content $destination\num_list.txt) -replace '\D','' | Set-Content $destination\num_list.txt
#list of client phone numbers generated from the client folder
$num_list = Get-Content "$destination\num_list.txt"
#for each file in the ring archive
(Get-ChildItem $source -File -Filter *.mp3 -Recurse) |
ForEach-Object {$recordings}
(Get-ChildItem $destination -Directory -Recurse) |
ForEach-Object {$clients}
#for each of the numbers in num_list
foreach ($num in $num_list) {
#match number to the same number in a file name
($recordings -match $num)
$target_recording = $Matches[0]
if ($target_recording -Match ([regex]::Matches($clients,'$num').Value)) {
Copy-Item -Path $target_recording.FullName -Destination $clients -Whatif
}
}
这就是你所追求的吗?
'Folder1234567890Text',
'Folder1234567891PDF',
'Folder1234567892XLS' |
ForEach-Object {New-Item -Path 'D:\Temp' -Name $PSItem -ItemType Directory}
'Folder1234567890Text.txt',
'Folder1234567891PDF.pdf',
'Folder1234567892XLS.xls' |
ForEach-Object {New-Item -Path 'D:\Temp' -Name $PSItem -ItemType File}
(Get-ChildItem -Path 'D:\Temp' -File) -match '\d{10}'
# Results
<#
Directory: D:\Temp
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 06-Feb-20 14:02 28817 23694d1213305764-revision-number-in-excel-book1.xls
-a---- 04-Dec-20 17:31 0 Folder1234567890Text.txt
-a---- 04-Dec-20 17:31 0 Folder1234567891PDF.pdf
-a---- 04-Dec-20 17:31 0 Folder1234567892XLS.xls
#>
(Get-ChildItem -Path 'D:\Temp' -Directory) -match '\d{10}' |
ForEach-Object {
Write-Verbose -Message "Processing $(($TargetFolderName = $PSItem.FullName))" -Verbose
(Get-ChildItem -Path 'D:\Temp' -File) -match '\d{10}' |
ForEach-Object {
If ($PSItem.Name -Match ([regex]::Matches($TargetFolderName,'\d{10}').Value))
{Move-Item -Path $PSItem.FullName -Destination $TargetFolderName -WhatIf}
}
}
# Results
<#
VERBOSE: Processing D:\Temp\Folder1234567890Text
What if: Performing the operation "Move File" on target "Item: D:\Temp\Folder1234567890Text.txt Destination: D:\Temp\Folder1234567890Text\Folder1234567890Text.txt".
VERBOSE: Processing D:\Temp\Folder1234567891PDF
What if: Performing the operation "Move File" on target "Item: D:\Temp\Folder1234567891PDF.pdf Destination: D:\Temp\Folder1234567891PDF\Folder1234567891PDF.pdf".
VERBOSE: Processing D:\Temp\Folder1234567892XLS
What if: Performing the operation "Move File" on target "Item: D:\Temp\Folder1234567892XLS.xls Destination: D:\Temp\Folder1234567892XLS\Folder1234567892XLS.xls".
#>
根据您在下面的评论更新没有理由对目录名称进行硬编码。
(Get-ChildItem -Path 'D:\' -Directory -Recurse) -match '\d{10}' |
ForEach-Object {$PSItem}
如果我正确理解了这个问题,您需要递归地在一个文件夹中找到所有名称中包含 10 位电话号码的 mp3 文件。 如果这样的数字对应于您保留在目标路径中的客户端文件夹名称之一,则应将文件复制到那里。
为此,我将使用查找哈希表,其中键表示现有客户端文件夹的电话号码,值存储客户端文件夹的完整路径。
$source = "D:\testInput\Ring\Archiver"
$destination = "D:\testOutput\Clients"
# create a lookup hashtable for all existing client folders
# the Key is the 10 digit phonenumber, the Value is the folders full path
$clientHash = @{}
Get-ChildItem -Path $destination -Directory | Where-Object { $_.Name -match '(\d{10})' } | ForEach-Object {
$clientHash[$matches[1]] = $_.FullName
}
# go through the files in the sourcefolder and copy all mp3 files with a matching phonenumber to the destination
Get-ChildItem -Path $source -Filter '*.mp3' -Recurse -File |
Where-Object { $_.BaseName -match '(\d{10})' } |
ForEach-Object {
# for better readability store the phonenumber in the file in a variable
$number = $matches[1]
if ($clientHash.ContainsKey($number)) {
# we have a client folder with that number
Write-Host "Copying file $($_.Fullname) to client folder '$($clientHash[$number])'"
Copy-Item -Path $_.Fullname -Destination $clientHash[$number] -WhatIf
}
else {
# unknown number
Write-Warning "Cannot copy file $($_.Fullname).. No client found for phone number $number"
}
}
-WhatIf
安全开关确保不进行复制,并且控制台中仅显示信息行,显示将发生的情况。 如果您对这一切都满意,请移除-WhatIf
开关并再次运行。
当然,如果您宁愿移动文件而不是复制它们,请将Copy-Item
更改为Move-Item
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.