Rekrul
The problem: I have a bunch of files in subdirectories. I want to recursively check the length of each filename and output it to a text file (ideally with the path) if the name is over 102 characters. I want to do this to check for names that are too long for burning to a disc and that will need to be renamed.
I tried Googling for a solution, but I can't find any that exactly match what I want to do and they use so many variable manipulations that when I try adapting them to what I want to do, they fail.
I grabbed the following code from somewhere a while back and at the time it seemed to work. Of course now it doesn't work and I have no idea why.
Code: Select all
echo off
SETLOCAL EnableDelayedExpansion
for %%F in (*.*) do (
echo %%F >tempfile.txt
for %%X in (tempfile.txt) do (set /A length=%%~zX-3)
if !length! gtr 102 echo %%F !length! >>!Results.txt
)
del tempfile.txt
It correctly writes the names to the temp file, so the problem is in the line that tries to count the length of that file. I have absolutely no clue why that line doesn't work, or why I can't specify a filename that starts with !, although I suspect it's the fault of the stupid delayedexpansion and some archaic rule that I'm not familiar with no matter how many times I try to understand why this is even a thing.
Last edited by Rekrul (20 May 2019 13:00)
----------------------------
#2 20 May 2019 15:58
bluesxman
If you're using delayed expansion, you will have problems trying to use "!" for stuff, as you've discovered.
I can see what that script is trying to do, but it's a bit over engineered for your problem -- though it would be a reasonable solution for finding the exact length of a string, I think you just need to know if it's too long or not, correct?
You haven't made it clear if it's the file name or full path you want to check. I've assumed file name.
To that end, try this
** UNTESTED **
Code: Select all
@echo off
REM recurse in current directory looking for files items
for /f "usebackq tokens=*" %%a in (`dir /a:-d /b /s *.*`) do (
REM invoke subroutine passing the file name and maximum permissible length
call :check "%%~a" 102
)
goto :EOF
:check
REM assuming you want the file name only
set name="%~nx1"
REM use this next line instead if you want to test the whole path
REM set name="%~1"
setlocal enabledelayedexpansion
REM substring expansion using passed param %2 as starting offset, get 1 character
REM if no character was found, the file name is within the maximum length
if "!name:~%2,1!" EQU "" (
echo:OK - "%name%"
) ELSE (
echo:TOO LONG - "%name%"
REM we don't know how long, because we didn't measure that
REM but we can show the extra characters
echo:Extra characters: "!name:~%2!"
)
endlocal
goto :EOF
cmd | *sh | ruby | chef
----------------------------
#3 15 Jul 2019 02:44
Rekrul
I'm sorry I haven't replied sooner. I thought of this problem as I was getting ready to burn a bunch of files to disc, and then promptly forgot about it, until the next batch was/is ready to be burned.
Thank you! Once I saw what you were doing, I changed and streamlined it a bit. The following seems to work reliably in all my tests;bluesxman wrote:
If you're using delayed expansion, you will have problems trying to use "!" for stuff, as you've discovered.
I can see what that script is trying to do, but it's a bit over engineered for your problem -- though it would be a reasonable solution for finding the exact length of a string, I think you just need to know if it's too long or not, correct?
You haven't made it clear if it's the file name or full path you want to check. I've assumed file name.
To that end, try this
Code: Select all
@echo off
for /R %%F in ("*.*") do (
set name=%%~nxF
set path=%%~pF
setlocal enabledelayedexpansion
if not "!name:~102,1!"=="" echo !path!!name! >>Results.txt
endlocal
)
I have a couple ideas for that, but I figure as long as it's working, I'll leave well enough alone. smile
Thanks again!