Windows:使用文件名正则表达式复制/移动文件?

Ian*_*oyd 10 windows file-management regex xcopy

我基本上运行:

C:\>xcopy [0-9]{13}\.(gif|jpg|png) s:\TargetFolder /s
Run Code Online (Sandbox Code Playgroud)

我知道xcopy不支持正则表达式文件名搜索。

我不知道如何确定PowerShell是否有Cmdlet复制文件的功能;如果支持,如何确定它是否支持正则表达式文件名匹配。

任何人都可以想出一种使用正则表达式文件名匹配来执行递归文件复制/移动的方法吗?

Dol*_*kle 5

我喜欢尽可能使用所有 Powershell 命令。经过一些测试,这是我能做的最好的。

$source = "C:\test" 
$destination = "C:\test2" 
$filter = [regex] "^[0-9]{6}\.(jpg|gif)"

$bin = Get-ChildItem -Path $source | Where-Object {$_.Name -match $filter} 
foreach ($item in $bin) {Copy-Item -Path $item.FullName -Destination $destination}
Run Code Online (Sandbox Code Playgroud)

前三行只是为了更容易阅读,如果需要,您可以在实际命令中定义变量。此代码示例的关键是“Where-Object”命令,它是一个接受正则表达式匹配的过滤器。需要注意的是,正则表达式支持有点奇怪。我在这里找到了一张 PDF 参考卡,左侧有支持的字符。

[编辑]

正如“@Johannes Rössel”所提到的,您还可以将最后两行缩减为一行。

((Get-ChildItem -Path $source) -match $filter) | Copy-Item -Destination $destination
Run Code Online (Sandbox Code Playgroud)

主要区别在于 Johannes 的方式进行对象过滤,而我的方式进行文本过滤。使用 Powershell 时,使用对象几乎总是更好。

[编辑2]

正如@smoknheap 所提到的,上述脚本将使文件夹结构变平,并将所有文件放在一个文件夹中。我不确定是否有保留文件夹结构的开关。我尝试了 -Recurse 开关,但没有帮助。我让它工作的唯一方法是回到字符串操作并将文件夹添加到我的过滤器中。

$bin = Get-ChildItem -Path $source -Recurse | Where-Object {($_.Name -match $filter) -or ($_.PSIsContainer)}
foreach ($item in $bin) {
    Copy-Item -Path $item.FullName -Destination $item.FullName.ToString().Replace($source,$destination).Replace($item.Name,"")
    }
Run Code Online (Sandbox Code Playgroud)

我确信有一种更优雅的方法可以做到这一点,但从我的测试来看,它是有效的。它收集所有内容,然后过滤名称匹配和文件夹对象。我不得不使用 ToString() 方法来访问字符串操作。

[编辑3]

现在,如果您想报告路径以确保一切正确。您可以使用“Write-Host”命令。下面的代码会给你一些关于发生了什么的提示。

cls
$source = "C:\test" 
$destination = "C:\test2" 
$filter = [regex] "^[0-9]{6}\.(jpg|gif)"

$bin = Get-ChildItem -Path $source -Recurse | Where-Object {($_.Name -match $filter) -or ($_.PSIsContainer)}
foreach ($item in $bin) {
    Write-Host "
----
Obj: $item
Path: "$item.fullname"
Destination: "$item.FullName.ToString().Replace($source,$destination).Replace($item.Name,"")
    Copy-Item -Path $item.FullName -Destination $item.FullName.ToString().Replace($source,$destination).Replace($item.Name,"")
    }
Run Code Online (Sandbox Code Playgroud)

这应该返回相关的字符串。如果您在某处什么也没得到,您就会知道哪个项目有问题。

希望这可以帮助


arm*_*nvg 3

PowerShell 是完成该任务的绝佳工具。您可以使用Copy-Item cmdlet 进行复制过程。您可以将其与其他 cmdlet 一起用于复杂的复制命令,这里有人正是这样做的:)

正则表达式使用 System.Text.RegularExpressions 命名空间中的 .NET RegEx 类,有关于这些类的快速操作方法

PowerShell 还具有-match 和 -replace 运算符,可在使用 copy-item 进行管道传输时使用

还有一些工具可以帮助您创建 RegEx 本身,例如RegEx buddy