使用powershell循环将文件复制到模式感知目录

rvpgvaaj  于 2023-02-08  发布在  Shell
关注(0)|答案(1)|浏览(119)

我有一个目录A,其中包含子目录a, b, c, d,每个子目录都包含带时间戳的文件夹(例如20230120)以及名称以日期和时间结尾的文件(例如file-202301200545
我想要的是将名称以今天日期结尾的文件复制到以今天日期结尾的文件夹中。
对不起,解释起来有点复杂,但我希望你能理解。
我编写了一个脚本来执行这个操作,但条件是我修复了每个目录。

$pattern = Get-Date -Format yyyyMMdd

$path = "D:\A\b\"
$Dest = "D:\A\b\\$pattern"
Get-ChildItem -Path $path -Recurse -Filter *$pattern* | Where-Object {$_.PSIsContainer -eq $false} | Move-Item -Destination $Dest

$path = "D:\A\c\"
$Dest = "D:\A\c\\$pattern"
Get-ChildItem -Path $path -Recurse -Filter *$pattern* | Where-Object {$_.PSIsContainer -eq $false} | Move-Item -Destination $Dest

$path = "D:\A\d\"
$Dest = "D:\A\d\\$pattern"
Get-ChildItem -Path $path -Recurse -Filter *$pattern* | Where-Object {$_.PSIsContainer -eq $false} | Move-Item -Destination $Dest

我需要帮助使用循环或任何其他技术,这将使我更容易做到这一点

nkcskrwz

nkcskrwz1#

假设目标目录已经存在:

Get-ChildItem -Directory -Path D:\A\[a-d] |
  Get-ChildItem -File -Recurse -Filter *$pattern* | 
  Move-Item -Destination { 
    Join-Path ($_.DirectoryName -split '\\')[0..2] $pattern
  } -WhatIf

注:上述命令中的-WhatIf公共参数 * 预览 * 操作。删除-WhatIf,并在确定操作将执行所需操作后重新执行。
如果要按需创建目标目录,请使用
New-Item -Type Directory -Force (Join-Path ($_.DirectoryName -split '\\')[0..2] $pattern)-New-Item-Force开关在与-Type Directory组合时确保返回预先存在的目录(如果有的话);否则,创建目录;在任一情况下,返回表示目录的System.IO.DirectoryInfo示例,其串化为其.FullName属性,即,串化为其完整的文件系统本机路径。
注:

  • 外部调用结合使用PowerShell wildcard expression-Directory开关来匹配感兴趣的顶级目录-注意使用字符范围[a-d]来匹配目录名称abcd
  • 内部调用作用于每个生成的目录,并通过-File开关递归地只搜索与模式匹配的 * files *。
  • 这种方法避免了对Where-Object {$_.PSIsContainer -eq $false}调用的需要,顺便说一句,该调用可以更接近PowerShell--习惯上表示为Where-Object { -not $_.PSIsContainer },在PowerShell (Core) 7+中--使用simplified syntaxWhere-Object -not PSIsContainer
  • 注意:尝试 * 单个 * Get-ChildItem调用很有诱惑力,例如

Get-ChildItem -Path D:\A\[a-d] -File -Recurse -Filter *$pattern*,但这实际上并不起作用,因为-File开关随后应用于 * D:\A\[a-d]通配符表达式解析为 * 的任何内容,并且由于结果是 * directories *,-File实际上将它们从进一步处理中"排除",从而导致实际上的no-op。

  • 也就是说,-File-Recurse的组合仅对 * literal * 输入路径有效,-File开关随后应用于其 * 子 *(后代)项。
  • Move-Item调用使用delay-bind脚本块来动态确定目标目录:
  • $_.DirectoryName包含每个输入文件的完整目录路径,(... -split '\\')[0..2]提取由3个组件组成的祖先路径,例如D:\A\c

相关问题