我已经完成了前三分之二的部分,但是我在最后一部分卡住了。我有一个脚本,它搜索具有特定名称的子文件夹,并将其内容向上移动一级。我还有一个脚本,它将文件从一个地方移动到另一个地方,如果文件已经存在,则重命名它们。我现在要做的是合并这两个脚本。下面是向上移动文件的脚本:
$sourceDir="E:\Deep Storage"
$searchFolder="Draft Materials"
Get-ChildItem -path $sourceDir -filter $searchFolder -Recurse |
ForEach-Object {
Get-ChildItem -File -Path $_.FullName |
ForEach-Object {
Move-Item -Path $_.FullName -Destination $(Split-Path -Parent $_.PSParentPath)
}
}
这里有一个在重命名已经存在的东西时移动它们的方法:
$sourceDir="E:\Test1"
$targetDir="E:\Deep Storage\Test1"
Get-ChildItem -Path $sourceDir -Filter *.* -Recurse | ForEach-Object {
$num=1
$nextName = Join-Path -Path $targetDir -ChildPath $_.name
while(Test-Path -Path $nextName)
{
$nextName = Join-Path $targetDir ($_.BaseName + "_$num" + $_.Extension)
$num+=1
}
$_ | Copy-Item -Destination $nextName -Verbose
}
最后,我尝试将两者杂交:
$sourceDir="E:\Deep Storage"
$searchFolder="Draft Materials"
Get-ChildItem -path $sourceDir -filter $searchFolder -Recurse |
ForEach-Object {
Get-ChildItem -File -Path $_.FullName |
ForEach-Object {
$num=1
$nextName = Join-Path -Path $_.FullName -Destination $(Split-Path -Parent $_.PSParentPath)
while(Test-Path -Path $nextName)
{
$nextName = Join-Path -Path $_.FullName -Destination $(Split-Path -Parent $_.PSParentPath) ($_.BaseName + "_$num" + $_.Extension)
$num+=1
}
$_ | Copy-Item -Destination $nextName
}
}
我觉得我的思路是对的,但经过两个小时的尝试,我还是没能让它工作。
编辑:提供我给出的确切语法
$sourceDir="E:\Deep Storage\Projects"
$searchFolder="Draft Materials"
$destinationPath = "$($sourceDir)\.."
Write-Host "OPERATION: Search for Folders Named" -ForegroundColor White -BackgroundColor DarkGreen -NoNewLine;
Write-Host " '$searchFolder' " -ForegroundColor Yellow -BackgroundColor DarkGreen -NoNewLine;
Write-Host "and Move Contents Up One Level" -ForegroundColor White -BackgroundColor DarkGreen;
Write-Host "SEARCHDIR: $sourceDir" -ForegroundColor White -BackgroundColor DarkGreen;
# Get all directories in specific folders inside the source directory
$folders = Get-ChildItem -Path $sourceDir -Directory | Where-Object {$_.Name -like "$searchFolder*" -or $_.FullName -like "*\$searchFolder\*"}
foreach ($folder in $folders) {
# Get all files in the current folder
$files = Get-ChildItem -Path $folder.FullName
foreach ($file in $files) {
$destinationFile = Join-Path -Path $destinationPath -ChildPath $file.Name
if (Test-Path $destinationFile) {
# If a file with the same name exists in the destination directory, rename it
$name = $file.Name
$extension = $file.Extension
$i = 0
while (Test-Path $destinationFile) {
$i++
$name = "{0}_{1}{2}" -f ($file.BaseName, $i, $extension)
$destinationFile = Join-Path -Path $destinationPath -ChildPath $name
}
Write-Host "Renaming $($file.Name) to $name"
}
Move-Item $file.FullName $destinationFile -Verbose -WhatIf
}
}
2条答案
按热度按时间3pvhb19x1#
以下是我阅读OP的帖子、代码和评论后得出的结论:
*语法选择:对于具有
Path
/LiteralPath
参数集(gci、Copy、Move、Rename等)的任何cmdlet,System.IO.FileSystemInfo | <Cmdlet>
语法可以成功处理<Cmdlet> -Path (System.IO.FileSystemInfo).FullNaame
表单中失败的项目,因为其名称中的特殊字符需要-LiteralPath
参数。在许多情况下,将
-Path
替换为-LiteralPath
(或其别名:-lp
)也可以。但是管道格式在扫描代码时读起来“更干净”(IMHO),如果你刚刚学习PowerShell,提醒你尽可能考虑管道化,避免中间变量。为了笑一笑,下面是上面代码的一个版本,使用ForEach-Object
尽可能多地管道化项目:knpiaxh12#
请尝试以下操作:
这不会删除原始位置,而是将所有内容从sourcePath移动到父位置。要删除原始位置,只需在末尾添加:
更新1: