0

I have this simple batch file I'd like to process files in subdirectories. I've played around with the for /R but I can't seem to get it to work. Any help would be very appreciated.

Thank you.

Here is the batch I have

@echo off
setlocal EnableDelayedExpansion

for %%A in ("*.mkv") do (
    echo file found  %%A

    for /f "tokens=1,2 delims=[im" %%D in ("%%~nA") do set "shortname=%%D[%%E"
    echo short name !shortname! >>J:\list.txt

)
7
  • Kind of... however my batch truncates the filename at the delims. I thought changing the /f to /R would solve the issue however it breaks the script instead. Commented Jul 1 at 1:49
  • 1
    for /f and /r switches are incompatible. You need the outer loop to be recursive, not the inner one (which doesn't list files, but just dissects a string): for /R %%A in ("*.mkv") do ..... I'm a bit sceptical about your delimiters though, i or m might exist in unexpected places. Commented Jul 1 at 5:25
  • It would be helpful to tell us what you expect to happen and what actually happened. In addition to Stephan's comments, >J:\list.txt would create a new file every single time the loop was executed so that only the very last result would appear in the file AND the space following !shortname! would be included in the result file. Either use '>>J:\list.txt" (which would append to any existing J:\list.txt) or enclose the entire for %%A` loop in a parenthesis pair and redirect; ie (for %%A…) )>J:\list.txt Commented Jul 1 at 7:34
  • If you show us the format of the filenames you're trying to processs, and the intended results, somebody may be able to assist you in achieving it. Please use the Edit facility to include that information. Commented Jul 1 at 7:50
  • Correct on the list.txt. it should be ">>" as opposed to ">". The delimiter is fine. it's not i or m, the delimiter is "[IM" in combination. For example, with the file "Thunderbolts [imdbid-tt20969586].mkv" it would find the file and add the filename to list.txt omitting the "[imdbid-tt20969586]" part. Starting at "[IM" and removing everything after it (except the extension). Commented Jul 1 at 19:04

1 Answer 1

0

You misunderstand what the string between =1 and " of the delims option does.

It is not a delimiter-string.

It is a set of characters , each one of which is a delimiter.

SET "delimiterstring=[im"

for %%A in ("*.mkv") do (
    echo file found  %%A

    for /f "tokens=1,2,3 delims=[im" %%D in ("%%~nA") do ECHO 1="%%D" 2="%%E" 3="%%F"
    
    set "shortname=%%~nA"
    SET "endpart=!shortname:*%delimiterstring%=!"
    ECHO lopped shortname="!endpart!"
    call SET "shortname=%%shortname:%delimiterstring%!endpart!=%%"
    echo short name "!shortname!"
)

Note that the for /f…%%D sets tokens 1,2 & 3 for the filename Thunderbolts [imdbid-tt20969586].mkv. The string is interpreted as [stringofdelimiters][stringofdata], repeated. Since '[','i','m' are defined as the delimiter characters, the tokens are generated as 1="Thunderbolts " 2="db" 3="d-tt20969586]"

Note also the Space at the end of the first token. The delims option does not permit a space as a delimiter, other than as the final character of the delims= string.

Your approach would thus also fail if "Thunderbolts " contained '[','i','m'

The remainder indicates one way to process the string. It sets endpart by replacing all characters up to and including delimiterstring with nothing then setsshortname to its initial value with [delimiterstring+endpart] replaced by nothing using the call parsing trick (used thousands of times on SO) to arrange the desired operation.

You should be careful about any "poison" characters (character with a special meaning to cmd such as !%~&^()

Note that you could also change delimiterstring to include the space in the desired position to remove the end-space from "Thunderbolts "

Sign up to request clarification or add additional context in comments.

5 Comments

You are correct. I apparently misunderstood the delimiter operation. That being said, I really didn't understand much of what you said either. (I'm not good at scripting at all). I understand that "[im" isn't being received as a single delimiter as I had thought and that they are 3 individual delimiters being found as such no matter where they are populated in the filename. Not what I want. I tested the example you gave and that didn't work either. It still removes any of the 3 delimiters, no matter where they appear in the filename.
Actually, once I added "setlocal enabledelayedexpansion" to the beginning, it worked fine. Thank you for that however, back to the initial issue, it only affects files in the current directory. I need it to run through files in subdirectories... and how would I change the delimiter string to remove the last space? Thank you very much.
1. The for /f…%%D is simply a demo to show how delims and tokens work. Remove it. 2. Use for /r %%A in place of for %%A to traverse the directory and subdirectories for *.mkv files. 3. change "delimiterstring=[im" to "delimiterstring= [im" to include the space in the delimiter string used in the processing of shortname. 4. Use IF "!endpart!" neq "%%~nA" echo short name "%%~dpA!shortname!" to omit the case that the filename does not contain delimiterstring and include the drivename+path in the reported filename.
In a quick test... that seems to be do exactly what I need! Thank you so much! Just on a side note, the line " for /f "tokens=1,2,3 delims= [im" %%D in ("%%~nA") do ECHO 1="%%D" 2="%%E" 3="%%F"" returns an error "[im" was not expected at this time." It doesn't appear to affect functionality so I'm not worried about it but though you might like to know.
The delims option does not permit a space as a delimiter, other than as the final character of the delims= string (In the narrative; second paragraph). That's why I didn't use "delims=%delimiterstring%". The sequence of characters in the delims option is irrelevant (except that space must be last if used) since that string is a set of delimiter characters. whereas with SET "endpart=!shortname:*%delimiterstring%=!" then it is used as a string where the sequence of the characters must match. The :*string=anotherstring part means change any characters up to string to anotherstring.

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.