Count filename length and output to file if over 102 characters?

Microsoft Windows
Post Reply
User avatar
MigrationUser
Posts: 336
Joined: 2021-Jul-12, 1:37 pm
Contact:

Count filename length and output to file if over 102 characters?

Post by MigrationUser »

20 May 2019 11:16
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's not recursive, but even in the current directory it doesn't work. If there is a file with a name over 102 characters, it creates a text file named "Results.txt", not "!Results.txt" and that contains the single word "length", rather than the expected contents of the variable. I want the results filename to start with "!" so that it will be at the top of the directory list.

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
Last edited by bluesxman (21 May 2019 09:42)

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.
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
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;

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
)
It outputs the path and name of any file with a name over 102 characters to a text file in the root dir. The only part I'm not entirely happy with is that it always gives the full path to the file from the root of the drive rather than the relative path starting in the current directory.

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!
Post Reply