【问题标题】:powershell move/delete directories not containing certain folderspowershell移动/删除不包含某些文件夹的目录
【发布时间】:2017-05-06 07:45:58
【问题描述】:

假设我们有一个包含多个子文件夹的文件夹,在每个子文件夹中都有不同数量的文件夹,这些文件夹以年份开始和结束日期命名。所有文件夹都包含一组不同的“年份文件夹”。

例如:
C:\Test\A\20050101-20051231
C:\Test\A\20060101-20061231
C:\Test\A\20070101-20071231
C:\Test\B\20140101-20141231
C:\Test\B\20150101-20151231
C:\Test\B\20160101-20161231
C:\Test\C\20090101-20091231
C:\Test\C\20100101-20101231
C:\Test\C\20110101-20111231

我需要帮助创建一个搜索这些文件夹然后移动根文件夹,在此示例中为“C:\A”,从 2009 年到 2016 年没有任何年份文件夹。不幸的是,我不能t 使用时间戳。

尝试从这个开始,但它只会从结果中排除子文件夹。

Get-ChildItem -Depth 1 | ?{ $_.PSIsContainer } | where {$_.name -notlike "2013"}|  Select-Object FullName

谢谢

【问题讨论】:

    标签: powershell move directory


    【解决方案1】:

    如果文件夹结构始终相同,这将起作用。

    Get-ChildItem -Path C:\Test -Directory | Where-Object -FilterScript {
        -not (
            Get-ChildItem -Path $_.FullName -Directory | 
            Where-Object -Property Name -In -Value (2009..2016)
        )
    }
    

    为在 2009 和 2016 之间没有年份的每个文件夹返回一个文件系统对象,在最后一个 } 旁边添加 | Remove-Item -Recurse 以删除文件夹。

    编辑:

    谢谢!刚刚注意到文件夹采用这种格式,20090101-20091231、20100101-20101231。那我该怎么办呢?

    稍微改了一下。为Get-ChildItem 使用Name 参数并切换内部where 语句的两侧,这样我们就可以使用like 运算符,并在名称后附加一个通配符。 没关系,这是各种各样的错误。只需切换到FilterScript 即可使用SubString() 方法。

    Get-ChildItem -Path C:\Test -Directory | Where-Object -FilterScript {
        -not (
            Get-ChildItem -Path $_.FullName -Directory -Name | 
            Where-Object -FilterScript { $_.SubString(0,4) -in (2009..2016) }
        )
    }
    

    【讨论】:

    • 谢谢,在我修改了子文件夹的名称之后?
    • 谢谢,我列出了所有文件夹,不仅是不包含 2009-2016 年文件夹的文件夹,因此由于某种原因过滤器不起作用。
    • 是的,那是我的错,没有测试。试试新的。
    • 太好了,刚刚添加 | Move-Item -Destination C:\temp\Data after } 并且效果很好。从这里回答的所有内容中学到了很多东西。谢谢!
    【解决方案2】:
    Get-ChildItem "c:\test\*\*"  | 
    select  @{N="YearDir";E={[int]$_.Name.substring(0, 4)}} , @{N="ParentDir";E={$_.Parent.fullname}} | 
    group ParentDir |
    %{ $year=$_.Group.YearDir; $dir=$_.Name; 2009..2016 | % { if ($_ -notin $year) {[pscustomobject]@{Dir=$dir;Year=$_}}} }
    
    #explication:
    
    #list dir with date
    Get-ChildItem "c:\test\*\*"  | 
    
    #build lisrt with extract year and parent dir
    select  @{N="YearDir";E={[int]$_.Name.substring(0, 4)}} , @{N="ParentDir";E={$_.Parent.fullname}} | 
    
    #group by parent dir
    group ParentDir |
    
    #filter between 2009 and 2016
    %{ $year=$_.Group.YearDir; $dir=$_.Name; 2009..2016 | % { if ($_ -notin $year) {[pscustomobject]@{Dir=$dir;Year=$_}}} }
    

    【讨论】:

      【解决方案3】:

      其他解决方案(PowerShell V5)

      Get-ChildItem "c:\test\*" -directory | % {
      $currentdir=$_.FullName
      $listcurrentdir=gci $currentdir -Directory | % {$_.name.Substring(0, 4)}
      2009..2016 | % { if ($_ -notin $listcurrentdir) {[pscustomobject]@{Dir=$currentdir; Year=$_}} }
      }
      

      【讨论】:

        【解决方案4】:

        您需要遍历这些年份并将它们与子文件夹名称进行比较。

        您可以在Where-Object 表达式中执行此操作:

        Get-ChildItem -Depth 1 -Directory |Where-Object {
            $Subfolders = Get-ChildItem $_.FullName |Select -Expand Name
            foreach($year in 2009..2016){
                if($Subfolders -contains $year){
                    return $false
                }
            }
            return $true
        }
        

        【讨论】:

        • 谢谢!刚刚注意到文件夹采用这种格式,20090101-20091231、20100101-20101231。那我该怎么办呢?
        • 将|ForEach-Object {$_.Substring(0,4)} 添加到$Subfolders = 管道
        • Get-ChildItem -Directory |Where-Object { $Subfolders = Get-ChildItem $_.FullName |Select -Expand Name|ForEach-Object {$_.Substring(0,4)} foreach( $year in 2009..2016){ if($Subfolders -contains $year){ return $false } } return $true }
        • 只需要找出从结果中移动/删除文件夹的最佳方法
        猜你喜欢
        • 2014-02-05
        • 1970-01-01
        • 2016-02-23
        • 1970-01-01
        • 2020-11-30
        • 2023-04-07
        • 2020-04-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多