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

I am using PowerShell and two days later I am struggling with this issue.

In the C: \ dir_1 directory I have many sub-folders (sub_1, sub_2, ..., sub_n). Each of them contains several text files. For each subfolder i = 1,2, ..., n, I want to move text files containing the string "My-String" to the directory C: \ dir_2 \ sub_i.

For example, if the X file in the path C: \ dir1 \ sub_5 contains the string "My-String", I want to move it to the C: \ dir_2 \ sub_5 folder. The destination folder already exists.

I tried several modifications of the following code, but it doesn't work:

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\$_"}}

      

So, basically, I tried to do this: ineach subfolder in dir_1, take the files containing the string and move them to a subfolder in dir_2 with the same name. I have tried several small modifications to this code, but I cannot get around my mistakes. Major error: "move-item: the given path format is not supported" ... any help?

+3


source to share


2 answers


I feel like I can do better, but this is my first approach

$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

can take file paths to enter its pipeline. We pass all files under $dir1

with -recurse

to get all of its children in subfolders. $results

will contain an array of match objects. One of the properties is the path to the corresponding file.



With all of these, $results

we then go through each one and extract the parent folder from the path. Then connect this folder to the path $dir2

to move it to its destination.

There are several assumptions we make here. We could take some of them into account, if necessary. I mentioned the one I know might be the problem in the first place.

  • There should be no other subfolders under "sub_1, sub_2, ..., sub_n" in your folders, otherwise they will try to navigate incorrectly. This can be solved with a little more rigorous manipulation. In an attempt to make the code concise with help -recurse

    created this caveat.
+6


source


Here's one liner that does what you want too:

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"}}}

      



And if you want it to be so broken up, as Matt replied:

$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"
        }
    }
}

      

+1


source







All Articles