Miguel's ques: Generalized move file by keyword in name.

Advanced Renamer forum
#1 : 07/12-24 22:37
Delta Foxtrot
Posts: 364
Hey Miguel,
I think this should do what you want. It searches the filenames for keywords in a list (line 10 in the pre-batch); if it finds a match it then searches the directories and deposits the file in the appropriate one.
EDIT: Oh, it also does everything in uppercase so "Texas" matches "TEXAS", "tEXAS", whatever...
https://drive.google.com/file/d/1Rxt9kI78nQ2BUNQ f01cV1X_kIssKjNWW/view?usp=sharing
END EDIT

//------------------------ PRE-BATCH SCRIPT:

// The following line holds the target directory:
const CurDir = "J:\\forum work\\Miguel1\\" ;

// And this next line is the csv filename:
var csv = CurDir + "test.csv";

// And the list of words to move files:
const matchList = "Spain Texas Italy" ;

const matchArr = matchList.toUpperCase().split(" ") ;

csv = '::\"' + csv + '\"' ;
const dirArr = [] ;
const dirArrNorm = [] ;
j=1;
while (csvLine = app.parseTags('<File Line:' + j + csv + '>')) {
dirArr[j-1] = csvLine.toUpperCase() ;
dirArrNorm[j-1] = csvLine ;
j++;
}

// matchList = keyword list delim w " "
// matchArr[] = keyword list as array (uppercase)
// dirArr[] = folder list as array (uppercase)
// dirArrnorm = folder list (original case)
//------------------------END PRE-BATCH


//------MIGUEL1 TEST - move files by keywords:
// FUNCTIONS:
function funFileSplit( newFilename ) {
fileWordArr = [] ;
fileWordCount = funFileNumWords() ;
for ( j = 1; j <= fileWordCount ; j++ ) {
fileWordArr[j-1] = app.parseTags( "<word:"+j+">" ).toUpperCase() ;
}
return fileWordArr ;

}
function funFileNumWords() {
l = 0 ;
wordCount = 0 ;
while ( app.parseTags( "word:"+l+">" ).length > 0 ) {
wordCount = l ;
l++ ;
if ( app.parseTags( "<word:"+(l+1)+">" ).length < 1 ) {
break;
}
}
return wordCount ;
}
//--------------------------------------------------

// Pass on files not matching target extensions:
fileExt = item.ext.toUpperCase() ;
switch ( fileExt ) {
case ".PNG":
case ".JPG":
case ".JPEG":
case ".TXT":
break ;
default:
return ;
}

fileName1 = item.newBasename ;
fileArr = funFileSplit( fileName1 ) ;
fileNameLower = item.newBasename ;
matchWord = "" ;
matchFound = false ;
// compare keywords to filenames:
for ( j = 0 ; j < matchArr.length ; j++ ) {
for ( k = 0 ; k < fileArr.length ; k++ ) {
if ( matchArr[j] == fileArr[k] ) { // we have a match
matchWord = matchArr[j] ;
matchFound = true ;
break ;
}
}
if ( matchFound ) {
break;
}
}
// compare matched keyword to directory names:
if ( matchFound ) { // find directory
for ( k = 0 ; k < dirArr.length ; k++) {
matchStr = dirArr[k] ;
if ( matchStr.search( matchWord ) !== -1 ) {
item.newPath = CurDir + dirArrNorm[k] ;
return ;
}
}
}

return ;
//--------------------------------------------------------------------

Let me know if there are problems with it.

Best,
DF

edited: 07/12-24 22:40
#2 : 08/12-24 11:48
Miguel
Posts: 163
Reply to #1:
Hi there, my friend.

What you have done is a lot of work. I'm so sorry that you lost your time with my stupid problems, and thank you from the bottom of my heart.
That's exactly what I wish for.

But -there's always a "but"- now I feel guilty. You've taken my examples literally.
Imagine 100 folders and 100 files, each with a different shared word in a different position. That's a lot of work.

QUESTION: Is there a possibility that:
const matchList = "Spain Texas Italy";
isn't limited to a list of names? Could it search for any shared word?

I’m a script collector. I have lots of them. Actually, I have a Python script that does that, but I’ve dreamed of having a script that does the same from Aren.

And I know that you are the man. If a Texan can't do it, no one else will. :)))

I'll let you send me to hell. :))
And Kim can kick me off the forum.

Miguel

P.S. And in all this, John Ninos hasn't said anything yet.
#3 : 08/12-24 18:53
Delta Foxtrot
Posts: 364
Reply to #2:

Hola Miguel,

1. Welcome to Literalville, buddy. My hometown. Let me apologize, I thought I understood what you wanted but apparently… well, you know… :)

2. Hardly any real work was involved. I basically added a nested loop to a script already written. I love nested loops. And I type pretty fast, and I spend a lot of time in front of the computer waiting for various processes to finish, so you're really doing me a favor giving me something to do to keep my hands and brain busy in the meantime. :)

3. I still don't know exactly what you want. You say, "Could it search for any shared word?"; my question back is "shared by what? It can't just be that the word appears in more than one filename, or you'd end up with folders named "the" and "in" for instance.

Anyway, I *think* what you are saying is you want the script to first compile a list of all words in all existing folder names, then check each word in each filename for a match against each of those folder words, right? If that's the case it *should* be pretty easy to fiddle, as long as you are willing to accept that the script may encounter filenames with more than one keyword, and obviously that file will always end up in the folder with the keyword it encounters first. In other words, I foresee possible unintended consequences, but depending on the folder structure, etc, maybe not. As always, the more precise the specification the more perfectly the program can run.

Let me know if I'm getting closer. And don't be sorry, or guilty, or any of that negative stuff. This is about as much fun as I have all day (pathetic, huh? :) Well, except I sometimes take my Corvette out for a little spin on the back roads. 8-D

Best regards amigo,
DF

PS. Does that python script do exactly what you want? If so, I'd like to get a look at it. I did a good bit of python and perl back when I was working for a dot-com. It would help understanding what you are looking for.

edited: 08/12-24 19:02
#4 : 08/12-24 20:29
Miguel
Posts: 163
Reply to #3:
Hi
I said:
Could it search for any shared word? Here I mean that the script will search the equivalents words in folders and in files.
Yesss you are closer.


Miguel.

https://drive.google.com/file/d/1n9dcSsYQ0B7a0AS decIVsLqdByFWYpaV/view?usp=drive_link
#5 : 09/12-24 00:55
Delta Foxtrot
Posts: 364
Reply to #4:

Hello Miguel,
Once more into the breach; see how this one works for ya...

//------------------------ PRE-BATCH SCRIPT:
// The following line holds the target directory:
const curDir = "J:\\forum work\\Miguel1\\" ;
// And this next line is the csv filename:
var csv = curDir + "test.csv";

csv = '::\"' + csv + '\"' ;
const dirArr = [] ;
const dirArrUC = [] ;
j=1;
while (csvLine = app.parseTags('<File Line:' + j + csv + '>')) {
lineUC = csvLine.toUpperCase() ;
dirArrUC[j-1] = lineUC ;
dirArr[j-1] = csvLine ;
j++;
}
// dirArr[] = folder list as array
// dirArrUC[] = folder list as uppercase array



//-----------------------------------MAIN SCRIPT:
//------MIGUEL2 TEST - move files by keywords:
// Pass on files not matching target extensions:
fileExt = item.ext.toUpperCase() ;
switch ( fileExt ) {
case ".PNG":
case ".JPG":
case ".JPEG":
case ".TXT":
break ;
default:
return ;
}
fileName1 = item.newBasename ;
fileArrUC = [] ;
// create array of filename words:
fileNameUC = fileName1.toUpperCase() ;
fileArrUC = fileNameUC.trim().split( /[\W_\-]+/ ) ;
// loop through folders:
for ( j = 0 ; j < dirArrUC.length ; j++ ) {
dirTestStr = dirArrUC[j] ;
// loop through words in file name:
for ( k = 0 ; k < fileArrUC.length ; k++ ) {
// Exclude A, AN, and short numbers:
if ( fileArrUC[k].length < 3 ) {
continue ;
} // end length if
matchTest = dirTestStr.search( fileArrUC[k] ) ;
if ( matchTest !== -1 ) {
item.newPath = curDir + dirArr[j] ;
} // end if
} // end inner for
} // end outer for
return fileName1 ;
//------------------------------------------

Let me know how this one works. :)

Best,
DF

edited: 09/12-24 00:59
#6 : 09/12-24 00:57
Delta Foxtrot
Posts: 364
Reply to #5:

I wish the forum preserved the indentation... you get used to seeing stuff indented in programs. It's very jarring! :)
#7 : 09/12-24 11:00
Miguel
Posts: 163
Reply to #5:

Hi,
In a previous post, I uploaded the wrong Python file. This is the correct one.

https://drive.google.com/file/d/1xQ5vMtzfg-4W2ao Oi26Zehviv_3tpkkf/view?usp=drive_link

#8 : 09/12-24 11:06
Delta Foxtrot
Posts: 364
Reply to #7:

Morning Miguel,

Try the new script in post #5, it should do what you want. I'll check out the Python script shortly, but I think this one does what you had in mind. :)

Best,
DF
#9 : 09/12-24 19:11
Miguel
Posts: 163
Reply to #8:
Hi there my friend.

I just tried your latest script and (drumroll) it works perfectly! It does exactly the same as my Python script but with the added convenience of being able to use it directly from Advanced Renamer.
I hope I didn’t trouble you too much. You’re amazing. Thank you so much for everything!
Here I show you a screen capture:

https://drive.google.com/file/d/1T7Sjc7_s4bEXj22 -jHXXGI5qmk79mI6K/view?usp=drive_link


Miguel

#10 : 09/12-24 19:27
Delta Foxtrot
Posts: 364
Reply to #9:

TA DA!

Anytime, my friend. No trouble at all; it was actually easier than the earlier efforts. Once I understood what you really wanted my only problem was realizing I had to eliminate short words and numbers like A, An, 01, etc. Practice makes better, I guess.

What else ya got? :)

Best,
DF