将包含字符串的文件移动到与原始文件同名的子文件夹 (PowerShell)

Move files that contain a string to a subfolder with the same name as the original (PowerShell)

我正在使用 PowerShell,这两天我一直在为这个问题苦苦挣扎。

在目录 C:\dir_1 我有很多子文件夹 (sub_1, sub_2, ..., sub_n)。他们每个人都包含几个文本文件。对于每个子文件夹 i=1,2,...,n,我想将包含字符串 "My-String" 的文本文件移动到目录 C:\dir_2\sub_i.

例如路径C:\dir1\sub_5中的文件X包含字符串"My-String",我想将其移动到位置C:\dir_2\sub_5。目标文件夹已存在。

我尝试对以下代码进行了多次修改,但都不起作用:

Get-ChildItem "C:\dir_1" | Where-Object {$_.PSIsContainer -eq $True} | Foreach-Object {Get-ChildItem "C:\dir_1$_" | Select-String -pattern "My-String" | group path | select name | %{Move-Item $_.name "C:\dir_2$_"}}

所以,基本上,我尝试做的是:foreach dir_1 中的子文件夹,获取包含该字符串的文件并将它们移动到 dir_2 中具有相同名称的子文件夹。我尝试对该代码进行一些小的修改,但我无法避免我的错误。主要错误是 "move-item: The given path format is not supported"...有帮助吗?

我觉得我可以做得更好,但这是我的第一个方法

$dir1 = "C:\temp\data\folder1"
$dir2 = "C:\temp\data\folder2"

$results = Get-ChildItem $dir1 -recurse |  Select-String -Pattern "asdf" 

$results | ForEach-Object{
    $parentFolder = ($_.Path -split "\")[-2]
    Move-Item -Path $_.Path -Destination ([io.path]::combine($dir2,$parentFolder))
}

Select-String 可以为其管道输入采用文件路径。我们使用 -recurse$dir1 下的所有文件提供给它,以获取子文件夹中的所有子项。 $results 将包含一组匹配对象。其中一个属性是匹配文件的路径。

对于所有这些 $results,我们然后遍历每个并从路径中提取父文件夹。然后将该文件夹与路径 $dir2 合并,以便将其移动到目的地。

我们在这里采用了几个假设。如果需要,我们可以考虑一些。我会先提到我知道的那个可能是个问题。

  1. 您的文件夹 "sub_1, sub_2, ..., sub_n" 下不应有任何其他子文件夹,否则它们将尝试错误地移动。这可以通过更多的字符串操作来解决。为了使用 -Recurse 使代码简洁,创建了此警告。

这里有一款衬垫也能满足您的需求:

Get-ChildItem "C:\dir_1" | Where-Object {$_.PSIsContainer -eq $True} | ForEach-Object {$SubDirName = $_.Name;ForEach ($File in $(Get-ChildItem $_.FullName)){If ($File.Name -like "*My-String*"){Move-Item $File.FullName "C:\dir_2$SubDirName"}}}

如果你想看到它像马特的回答一样分解:

$ParentDir = Get-ChildItem "C:\dir_1" | Where-Object {$_.PSIsContainer -eq $True}
ForEach ($SubDir in $ParentDir){
    $SubDirName = $SubDir.Name
    ForEach ($File in $(Get-ChildItem $SubDir.FullName)){
        If ($File.Name -like "*My-String*"){
            Move-Item $File.FullName "C:\dir_2$SubDirName"
        }
    }
}