none
[Solved] PowerShell search string and copy file RRS feed

  • Question

  • I'm preparing a script to find some text inside the files ('test' and 'test1' are the keywords in this scenario) and once all the files have been found, they should be copied to a different location while maintaining the folder structure.

    For example: The path c: \ src contains 10 files, 3 include the search words. These 3 files should be copied to c: \ dst \

    Everything should be recursive for all subdirectories of c: \ src.

    So if in the path c: \ src \ somefolder \ there were other files with the same search words, they should be copied to c: \ dst \ somefolder \

    Here my code:

    Write-Host ""
    Write-Host "Note: Path must end with '\'"
    Write-Host ""
    
    # Var.
    $sourceDir = Read-Host 'Source path'
    $targetDir = Read-Host 'Destination path'
    
    # Decl.
    $tree = gci -Directory -Name -Recurse $sourceDir
    
    # Check if $sourceDir exist
    if(!(Test-Path -Path $sourceDir )){
      "Source is not a valid path!" ; pause
    exit 1
    }
    
    # Check (and create) $targetDir
    if(!(Test-Path -Path $targetDir )){
      mkdir $targetDir -Force
    }
    
    # Rebuild Tree
    foreach ( $folders in $tree ) { mkdir $targetDir\$folders -Force }
    
    # Copy Founded Files
    $ftc = Get-ChildItem $sourceDir -Recurse | Select-String "test","test2" | Select Path |
    foreach{    
      $targetFile = $targetDir + $_.FullName.SubString($sourceDir.Length); 
      Copy-Item $_ -destination $targetFile
    }

    I can not figure out where the error is. Does anyone know how I can solve it ?

    The proposed error is: "Copy-Item: Unable to find the unit. A unit named '@ {Path = C' does not exist."

    From what I could understand it seems that the script can not find the path of the source file.
    • Edited by Ihyae Thursday, May 17, 2018 3:27 PM Solved
    Thursday, May 17, 2018 12:43 PM

Answers

  • Write-Host ""
    Write-Host "Note: Path must end with '\'"
    Write-Host ""
    
    # Var.
    #$sourceDir = Read-Host 'Source path'
    #$targetDir = Read-Host 'Destination path'
    $sourceDir = "C:\Source"
    $targetDir = "C:\Destination"
    
    # Decl.
    $tree = gci -Directory -Recurse $sourceDir
    
    # Check if $sourceDir exist
    if(!(Test-Path -Path $sourceDir )){
      "Source is not a valid path!" ; pause
      exit 1
    }
    
    # Check (and create) $targetDir
    if(!(Test-Path -Path $targetDir )){mkdir $targetDir -Force}
    
    # Rebuild Tree
    foreach ( $folder in $tree ) {
        mkdir ($folder.fullname.replace($sourceDir,$targetDir)) -Force |Out-Null
    }
    
    # Copy Found Files
    $ftc = Get-ChildItem $sourceDir -Recurse | Select-String "test","test2" | Select -Unique Path |
    foreach{
      $sourceFile = Get-Item $_.Path
      $targetFile = $sourceFile.Fullname.Replace($sourceDir,$targetDir)
      $sourceFile | Copy-Item -Destination $targetFile
    }
    • Marked as answer by Ihyae Thursday, May 17, 2018 3:27 PM
    Thursday, May 17, 2018 3:27 PM

All replies

  • Select string will not get you what you want as it will return duplicates.

    Get-ChildItem $sourceDir -Recurse | 
        Select-String test,test2 -List | 
        Select Path |
        ForEach-Object{
            # the following line makes no sense
            $targetFile = $targetDir + $_.SubString($sourceDir.Length); 
            Copy-Item $_.Path -destination $targetFile
        }
    



    \_(ツ)_/

    Thursday, May 17, 2018 1:07 PM
  • Write-Host ""
    Write-Host "Note: Path must end with '\'"
    Write-Host ""
    
    # Var.
    #$sourceDir = Read-Host 'Source path'
    #$targetDir = Read-Host 'Destination path'
    $sourceDir = "C:\Source"
    $targetDir = "C:\Destination"
    
    # Decl.
    $tree = gci -Directory -Recurse $sourceDir
    
    # Check if $sourceDir exist
    if(!(Test-Path -Path $sourceDir )){
      "Source is not a valid path!" ; pause
      exit 1
    }
    
    # Check (and create) $targetDir
    if(!(Test-Path -Path $targetDir )){mkdir $targetDir -Force}
    
    # Rebuild Tree
    foreach ( $folder in $tree ) {
        mkdir ($folder.fullname.replace($sourceDir,$targetDir)) -Force |Out-Null
    }
    
    # Copy Found Files
    $ftc = Get-ChildItem $sourceDir -Recurse | Select-String "test","test2" | Select -Unique Path |
    foreach{
      $sourceFile = Get-Item $_.Path
      $targetFile = $sourceFile.Fullname.Replace($sourceDir,$targetDir)
      $sourceFile | Copy-Item -Destination $targetFile
    }
    • Marked as answer by Ihyae Thursday, May 17, 2018 3:27 PM
    Thursday, May 17, 2018 3:27 PM