根据条件将文件移动到其父级内部的新文件夹

时间:2018-07-09 16:06:42

标签: powershell file-management

我目前正在Powershell中从事一个项目,我确实并不十分熟悉。我已经很近了,并做了一些环顾四周,以使我更加接近,但是我为这个大时代而感到困惑。

目标是递归地在目录中搜索以“ \_7Y_”开头的文件(这是我根据文件的使用期限编写的另一个脚本完成的),并在该文件的父目录中创建了一个新的子目录,然后移到那里。例如,如果我有~\desktop\old\\_7Y_OldFile.txt,我希望该文件转到~\desktop\old\\_7Y_\\_7Y_OldFile.txt,并且我希望它为每个文件递归执行该操作。

我的脚本当前正在按预期方式创建文件夹,但是仅选择一个新文件夹将项目移动到其中。我认为这是由于$ child变量仅选择了一个值,因为在移动文件后脚本继续执行,但是在尝试查找文件以移动文件时遇到错误。缺少手动告诉每个父母(此过程最终将自动完成)的过程,我想知道如何做才能区分每个$ child的举动。

根据我的理解,只要我使用-force,就不需要先执行New-Item,然后再进行Move-Item,但这也不是我的经验。任何帮助将不胜感激。

我为奇怪的格式和技术表示歉意-我确实一直在不断学习powershell。

[CmdletBinding()]
Param(
[Parameter(mandatory=$true)]
[ValidateScript({Test-Path $_ -PathType 'any'})]
[string] $InputFilePath
)
#this sets the filepath parameter to mandatory, so you will need to input 
your own filepath!

$directoryInfo = Get-ChildItem $InputFilePath -recurse | Measure-Object 
$7Yno = Get-ChildItem $InputFilePath -recurse | Where-Object {$_.Name -like '_7Y_*.*'} | Measure-Object
#These are used as the conditions for the if statements
#directoryInfo gets the number of files in the directory; 7Yno gets the number of files prepended with _7Y_ in the directory

$Confirmation = Read-Host "Are you SURE you want to proceed with this operation? All selected files in the given directory will be moved to new directories! This action is irreversable. Your selected directory is $InputFilePath. Enter 'Yes' to proceed"

if ($Confirmation -eq "Yes") {

    if ($directoryInfo.count -gt 0 -and $7Yno.count -gt 0){   #Check: Files in directory and files prepended with _7Y_ in directory.

    $children = @((Get-ChildItem $InputFilePath -recurse | 
        Where-Object {$_.Name -like "_7Y_*.*"}).directory.fullname | 
            Get-Unique)
    $Files = @(Get-ChildItem $children -recurse | 
        Where-Object {$_.Name -like "_7Y_*.*"})

        foreach($child in $children){
            $7yPath = "$child\_7Y_"
            New-Item -itemtype Directory -path $7yPath -force
        }
        foreach($file in $Files){
            Move-Item $file.fullname -destination $7yPath -force
        }
    }

    if ($directoryInfo.count -gt 0 -and $7Yno.count -eq 0){   #Check: Files in directory, but no files prepended with _7Y_ in directory.
    Read-Host "There are no files prepended with _7Y_ in this directory!"
    }

    if ($directoryInfo.count -eq 0){                            #Check: No files in directory.
    Read-Host "There are no files in this directory!"
    }
}

1 个答案:

答案 0 :(得分:0)

您是IMO使事情复杂化了。

  • 带有前缀的Get-ChildItem递归
  • 如果父文件夹名称不等于前缀
    • 检查文件夹是否存在,如果没有创建
    • 将文件移动到文件夹

编辑:仅使用一次即可精简脚本 "$($_.Directory)\$Prefix"

Push-Location 'X:\Folder\to\start'
$Prefix = '_7Y_'
Get-ChildItem -File -Filter "$Prefix*" -Recurse | 
  Where-Object {$_.Directory.Name -ne $Prefix} |
    ForEach-Object {
      $DirPrefix = "$($_.Directory)\$Prefix"
      If(!(Test-Path $DirPrefix)){
        Md $DirPrefix | Out-Null
      }
      $_ | Move -Destination $DirPrefix

    }

/ F之前的样本树

└───one
    │   _7Y_one.txt
    │
    └───two
        │   _7Y_two.txt
        │
        └───three
            │   _7Y_three.txt
            │
            └───four
                    _7Y_four.txt

运行脚本后

───one
   ├───two
   │   ├───three
   │   │   ├───four
   │   │   │   └───_7Y_
   │   │   │           _7Y_four.txt
   │   │   │
   │   │   └───_7Y_
   │   │           _7Y_three.txt
   │   │
   │   └───_7Y_
   │           _7Y_two.txt
   │
   └───_7Y_
           _7Y_one.txt

解释这一行:

If(!(Test-Path "$($_.Directory)\$Prefix"))
  • 在字符串表达式内处理对象$_.Directory的属性时,必须将其包含在$()中才能明确/强制求值。
  • Test-Path返回$ true / $ false,以在If-中使用-not或用!(Test-Path ...)取反来反转条件。