0

I have a large number of images stored in a single folder and sorted through them to choose which to copy to certain folders such as "scenery" or "technical" and created a list of partial filenames for each folder in a text file. eg. Scenery.txt

4811
4819
4820

These are the unique file numbers which are part of the full filenames, for example:

C:\Users\drewb\Pictures\2018_08_Inuvik\All\DSC_4811.jpg

I have a script in powershell which has worked for me when I had a list of the full filenames listed in a .txt file but to save time due to a larger number of photos I only wrote the image number. I'm hoping there's a way to create an array of this list and feed it as a variable in the full filename in a loop, but any suggestion is appreciated.

The code which worked for me with the full names in the .txt was

Get-Content C:\Users\drewb\Pictures\2018_08_Inuvik\Technical.txt | ForEach-Object {copy-item $_ C:\Users\drewb\Pictures\2018_08_Inuvik\Technical}

SOLVED: I solved it by concatenating the file path to the names and the file extension in excel then used used the PS script I previously used. However, I feel like there must be a more direct way this could be scripted.

  • are the image numbers in the file each on a new line or are they next to each other? – SimonS Sep 4 '18 at 6:42
  • I believe you need a smarter tool than just CMD or powershell. – Andreas Sep 4 '18 at 19:32
  • The image numbers are on each new line. Do you have any ideas on what i could use? – Drew Branson Sep 4 '18 at 22:46
  • @DrewBranson I'm not understanding the question 100%. which pictures must go in which folder? you want to create a folder e.g 4811 and all Files which have 4811 in their FileName should go into this folder? please elaborate a bit, by editing your question – SimonS Sep 5 '18 at 7:45
  • You question needs a little more clarity. Seems like Powershell is a good solution, but it's tough to answer without another explanation. You could extract all the numeric values from your images, if they are all named the same way as your example image, like this: gci | select -ExpandProperty BaseName | % { $_.Split('_')[1] }. – root Sep 5 '18 at 14:21
1

Short answer

If the current directory contains pictures whose file names follow the same pattern DSC_XXXX.jpg (where XXXX is a number) and a file named Technical.txt containing some of these numbers, the following command would copy to the Technical folder (assuming it exists in the current directory) all files for which a number is provided in the Technical.txt file:

Get-Content Technical.txt | ForEach-Object { Copy-Item "DSC_$_.jpg" Technical }

If the Technical.txt and picture files and the Technical directory are not in the current directory, full or relative paths have to be provided, for example:

Get-Content c:\path1\to\Technical.txt | ForEach-Object { Copy-Item "c:\path2\to\pictures\DSC_$_.jpg" c:\path3\to\Technical }

Explanation

  • The "DSC_$_.jpg" expression in the command is used to generate the picture file name from the number that was read from the Technical.txt file, which is the current pipeline object (i.e. $_). It simply adds DSC_ as a prefix and .jpg as the extension.
  • Get-Content reads the content of the Technical.txt file.
  • ForEach-Object executes its script block arguments (enclosed in curly braces, i.e. {}) for each object in the pipeline, in this case, each line of text returned by Get-Content.

Testing this solution (online or locally)

The easiest is to try this solution online.

Otherwise, the following snippet can be used to create in the current directory a test folder containing an example Technical.txt file and fake picture files following the pattern mentioned in this answer along with an empty Technical directory (be careful: you have to change .\test to something else if you already have a test folder in the working directory:

mkdir -ErrorAction SilentlyContinue .\test\Technical
Out-File .\test\DSC_4811.jpg; Out-File .\test\DSC_4812.jpg; Out-File .\test\DSC_4813.jpg;
Out-File .\test\DSC_4814.jpg; Out-File .\test\DSC_4819.jpg; Out-File .\test\DSC_4820.jpg;
"4811`n4819`n4820" > .\test\Technical.txt

(In the third line, `n represents an end of line character (the back-tick (`) is an escape character in PowerShell).

It generates the following files:

.\test\DSC_4811.jpg    .\test\DSC_4812.jpg    .\test\DSC_4813.jpg
.\test\DSC_4814.jpg    .\test\DSC_4819.jpg    .\test\DSC_4820.jpg
.\test\Technical.txt

After the command provided as an answer is executed (Get-Content .\test\Technical.txt | ForEach-Object { Copy-Item ".\test\DSC_$_.jpg" .\test\Technical }), the files are:

.\test\DSC_4811.jpg              .\test\DSC_4812.jpg              .\test\DSC_4813.jpg
.\test\DSC_4814.jpg              .\test\DSC_4819.jpg              .\test\DSC_4820.jpg
.\test\Technical.txt
.\test\Technical\DSC_4811.jpg    .\test\Technical\DSC_4819.jpg    .\test\Technical\DSC_4820.jpg

To clean up:

ri -Recurse .\test

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.