#1 : 13/12-21 20:38 John
Posts: 15
|
I am trying to copy an image library to a new location and cleanup some unneeded files.
Is it possible, within a script, to skip files based on certain criteria, ie certain files in the list would not be copied. In my case I have a list which includes file pairs of JPG & RAW, where I only want to copy the RAW file, but other cases in the same selection list where I only have RAW files, and some that are only JPG. So I want to skip JPGs if there is also a RAW file, and copy the JPG if there is only a JPG. I have created a Pre Batch Script that scans the list and creates a list of JPGs that should be ignored, now I need to work out how to handle that in the main Script method. |
#2 : 14/12-21 13:43 David Lee
Posts: 1125
|
Reply to #1:
I found it easier to flag the names of the .raw files in the Pre batch script. Then in the main script set newPath (as defined in the Pre batch script) for all .raw files and for .jpg files where the .raw flag does not exist. ie... Select Batch mode: Copy Pre batch script: ***************** newPath = 'C:\\Users\\YourName\\YourNewPath\\' ; var rawFiles = {}; for (j = 0; j < app.itemCount; j++) { item = app.getItem(j); if (item.ext == '.raw') rawFiles[item.name] = 1; } Main Script: ************* log(!rawFiles[name]); if (item.ext == '.raw' || !rawFiles[item.name]) item.newPath = newPath; Note that JavaScript follows the Unix convention using "\" as the separator in a file path and since "\" is also the "escape" character it must be replaced by "\\" when used within a text string. The variable rawFiles is an object that simulates an associative array - ie an array indexed by a string variable. (Note that a Google search will usually tell you that associative arrays are not supported by JavaScript and this workaround can be risky in more complex circumstances). In the Pre batch script an element of rawFiles is created for each .raw file, indexed by the filename, and with the dummy value = 1. In the Main script "rawFiles[item.name]" will return "undefined" if it was not set in the Pre batch script (ie there was no .raw file with this filename). "Undefined" is equivalent to FALSE so applying the NOT operator (!) will return the value TRUE. |
#3 : 14/12-21 14:47 John
Posts: 15
|
Reply to #2:
Thanks for the suggestion David, I'll look at it more closely but I'm not sure if it works for me. I tried to keep the description of the problem simple, but actually there can be more than just JPG & RAW - There can also be *.ON1 files (like XMP) and *.MOV files, so the JPG was easier to mark for deletion. I also have 2 types of RAW files - .ORF & .DNG. I think I might see a way to adapt your solution. Do I understand the main script code correctly: the ignored JPGs will have an empty newPath if the RAW exists, and that means they won't get copied? I am using an associative array, but had to search a bit to find your solution. I have to review my strategy as I realised today that my current solution only works in a single folder. My files are in sub(sub(sub))folders and the numbering from two cameras (DJI) isn't unique - DJI resets the file counter to 0001 for panoramas and timelapse sequences, within a separate subfolder - I'll need to use the path or parent folder to identify image file groups & not just the item.name I think. Thanks again, I appreciate your help |
#4 : 14/12-21 14:51 John
Posts: 15
|
PS here is my script:
Pre Batch (I'm using a normal array - surprised it works) current_group = ""; keep_jpg = []; for (var i=0; i<app.itemCount; i++) { basename = app.getItem(i).name; if(basename != current_group){ current_group = basename; keep_jpg[current_group] = 1; } type = app.getItem(i).ext; if(type == '.dng' || type == '.orf'){ keep_jpg[current_group] = 0; } } Main (renames unwanted jpgs. Should use !keep_jpg[item.name] instead of comparing to 0) var type = item.extension; if(type == '.jpg' && keep_jpg[item.name] == 0){ return(item.name + 'DELME' + item.extension); }else{ return(item.name + item.extension); } |
#5 : 14/12-21 17:06 David Lee
Posts: 1125
|
Reply to #4:
Try this... Pre batch script: ***************** var rawFiles = {}; for (j = 0; j < app.itemCount; j++) { item = app.getItem(j); if (item.ext == '.orf' || item.ext == '.dng') rawFiles[item.path + item.name] = 1; } main script: ************ if (item.ext == '.orf' || item.ext == '.dng' || !rawFiles[item.path + item.name]) { item.newPath = item.path + 'copies'; } The rawFiles object is now indexed by the full path of each raw file name (without the extension), which should remove the issue with duplicate names in different sub-folders. Copied files are now moved into subfolders named "copies" within each original folder . Note that you do not need a return statement since you are merely copying files and not renaming them so that all the script is doing is setting the New Path for the Copy Batch Mode (I assume that you ARE selecting Batch mode = Copy instead of Rename?) I meant to point out in my original reply that the Copy mode will attempt to copy ALL files into the folder defined by newPath. However the files that we do not want to copy will still have newPath set to the original folder and so the copy attempt will fail with Error 101: "Unknown error: The process cannot access the file because it is being used by another process". **** Edit **** If you also have Raw files with the .raw extension then change line 4 of the Pre batch script to: if (item.ext == '.orf' || item.ext == '.dng' || item.ext == '.raw') rawFiles[item.path + item.name] = 1; |
#6 : 14/12-21 20:30 John
Posts: 15
|
Reply to #5:
Thanks once more David. I like this method and I'll integrate this into my scripts. A couple of years ago I created a script method to handle importing of files from several cameras but I didn't try to remove the unnecessary JPGs. As I haven't looked at it since then I forgot how everything works.... |