1

I have a list of files in a file named files.txt.

I have a folder, FlacTest, with a mix of files that appear in the list and files that don't.

I want to move the files that appear in the list out of the folder FlacTest and into a second folder - FlacRecovery.

Here is my code:

$file_list = Get-Content 'C:\files.txt'
$search_folder = 'C:\FlacTest'
$destination_folder = 'C:\FlacRecovery'

foreach ($file in $file_list) {$file_to_move = Get-ChildItem -Path $search_folder -Filter $file -Recurse -ErrorAction SilentlyContinue -Force | % { $_.FullName}
if ($file_to_move) {
    Move-Item $file_to_move $destination_folder}
}

When I run the script it does not error but nothing happens. Is there something wrong with the code?

5
  • Are the files all in the root of the search folder, or are some in subfolders? How are the files to be moved listed in files.txt, just by name or with full paths? Commented Sep 8, 2017 at 12:31
  • Change this part if ($file_to_move.Exists) { $file_to_move | Move-Item -Destination $destination_folder} } and remove | % { $_.FullName} Commented Sep 8, 2017 at 12:33
  • 1
    @Matt: Your code works when I tested it, but I assumed the text file contains a list of just filenames and extensions (with no path) and that the file was in the root of the search folder. If the text file contains full paths then it does not work. Commented Sep 8, 2017 at 12:35
  • Many thanks both - I had full paths in my files.txt Commented Sep 8, 2017 at 12:43
  • Assumedly you just moved $file to the -Path parameter then? Btw you can submit your own answer to your own question and then mark it as accepted if you've solved it. Commented Sep 8, 2017 at 12:52

1 Answer 1

1

Work with the pipeline. One way to solve this is:

  • take paths from text file (Get-Content)
  • convert them to actual file objects (Get-Item)
  • filter them down (Where-Object + Test-Path)
  • move the remaining ones (Move-Item)

Wrapped for legibility (the backticks are here for line-continuation):

$destination_folder = 'C:\FlacTest'

Get-Content C:\files.txt `
| Get-Item `
| Where-Object { -not (Test-Path "$destination_folder\$_.Name") } `
| Move-Item -Destination $destination_folder

No manual loops, just a single pipeline.

For throw-away one-liners this can be trimmed down by use of aliases:

cat C:\files.txt | gi | ? {-not (Test-Path "C:\FlacTest\$_.Name")} | mv C:\FlacTest
Sign up to request clarification or add additional context in comments.

3 Comments

If you leave the pipe character on the end of the previous line, you can do away with the pesky backtick character.
I know. I actually prefer the "straight line of pipes" variant in a script, I think it's visually nice and expressive. The backticks don't bother me that much. (Besides, I wanted to make the point how line continuation works in PS)
I agree that it is more visually appealing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.