List all files with filenames longer than 255 chars?

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
pstein
Posts: 125
Joined: 09 Nov 2011 01:42

List all files with filenames longer than 255 chars?

#1 Post by pstein » 28 Nov 2015 11:51

Occasionally I faced the situation where I cannot backup/copy/delete files because they are stored in a sub sub sub directory with an alltogether
(drive+path+filename) length of more than 255 chars.

As you know Windoes (7) allows only a max filename length of 255 chars.

In order to find out critical files in advance I want to navigate through all files in a directory tree with lets say top node folder

H:\archive\

and list all files with a filename length greater than 255.

How can I achieve this in a DOS batch script?

When the files are listed the filename length should be prepended (=displayed left of the filename on the output line).

Thank you
Peter

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: List all files with filenames longer than 255 chars?

#2 Post by Aacini » 28 Nov 2015 13:43

Code: Select all

@echo off
cd /D %1
call :treeProcess "%cd%"
goto :eof


:treeProcess curDir
setlocal EnableDelayedExpansion

rem Check the files in this folder
for %%f in (*.*) do (
   set "name=%~1\%%f"
   if "!name:~255,1!" neq "" (
      for /L %%i in (255,1,500) do if "!name:~%%i,1!" neq "" set /A len=%%i+1
      echo !len!: !name!
   )
)

rem Recursive call itself with all subfolders
for /D %%d in (*) do (
    cd "%%d"
    call :treeProcess "%~1\%%d"
    cd ..
)

exit /b

Place the folder to review in the parameter, for example:

Code: Select all

test.bat H:\archive

The method that get the length of the name could be changed by another, more efficient one if you wish.

Antonio

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: List all files with filenames longer than 255 chars?

#3 Post by dbenham » 28 Nov 2015 13:58

@pstein

Are you trying to use Windows to access a non-Windows file system that contains paths greater than length 255?
Or are you trying to determine if an as yet non-existent destination path has a length that exceeds the Windows limit?


Dave Benham

Squashman
Expert
Posts: 4486
Joined: 23 Dec 2011 13:59

Re: List all files with filenames longer than 255 chars?

#4 Post by Squashman » 28 Nov 2015 15:59

I thought ROBOCOPY fixes that issue.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: List all files with filenames longer than 255 chars?

#5 Post by foxidrive » 29 Nov 2015 06:21

Squashman wrote:I thought ROBOCOPY fixes that issue.


It does have the ability to copy it anyway - I struck the prompt recently.
Total Commander can do it too.

pstein
Posts: 125
Joined: 09 Nov 2011 01:42

Re: List all files with filenames longer than 255 chars?

#6 Post by pstein » 29 Nov 2015 07:05

Meanwhile I found a smart one-liner solution which works for calculating the length:

set mystring=hello sample
for /f "tokens=1 delims=:" %%a in ( '^(echo."%mystring%"^& echo.!@#^)^|findstr /O /C:"!@#" ' ) do set /a Length=%%a-5
echo Length=%Length%

However I have a problem with putting this working string length calculating command into a loop in batch script:

setlocal enabledelayedexpansion
for /r H:\archive %%a in (*) do (
set currfile=%%a
echo cf=!currfile!
for /f "tokens=1 delims=:" %%i in ( '^(echo."!currfile!"^& echo.!@#^)^|findstr /O /C:"!@#" ' ) do set /a length=%%i-5
echo Length=!length!
if !length! gtr 100 ( echo longer than 100 )
)


currfile is displayed correctly but the length is NOT echoed.

What wrong?
Maybe I have to mask/escape the closing round brackets inside the outer "for" loop?

Peter

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: List all files with filenames longer than 255 chars?

#7 Post by foxidrive » 29 Nov 2015 07:23

Try replacing the ! in two places with Q

Code: Select all

^& echo.!@#^)^|findstr /O /C:"!@#"

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: List all files with filenames longer than 255 chars?

#8 Post by Aacini » 29 Nov 2015 08:42

Ops! It seems I misunderstood this problem!

I don't know Windows 7, but I do know that several internal Windows functions have a limit in the lenght of the names they return. After I read this phrase: "As you know Windoes (7) allows only a max filename length of 255 chars", I assumed that this problem is about get long pathnames without use the standard methods to do so (like FOR command) because they fail, so my first solution above use a recursive subroutine to do that. Getting the length of the pathname is just a minor problem that can be solved with a method as simple as a FOR loop with a given range of values.

However, if a FOR /R command correctly returns names longer than 255 (as the last pstein's example show), then this problem can be solved in a much simpler way:

Code: Select all

@echo off
setlocal EnableDelayedExpansion

for /R H:\archive %%f in (*.*) do (
   set "name=%%f"
   if "!name:~100,1!" neq "" (
      for /L %%i in (100,1,500) do if "!name:~%%i,1!" neq "" set /A len=%%i+1
      echo !len!: !name!
   )
)

The method to get the length of the path can be changed by a more efficient one, like this:

Code: Select all

@echo off
setlocal EnableDelayedExpansion

for /R H:\archive %%f in (*.*) do (
   set "name=%%f"
   if "!name:~100,1!" neq "" (
      set "len=0"
      for /L %%i in (10,-1,0) do (
         set /A "newLen=len+(1<<%%i)"
         for %%j in (!newLen!) do if "!name:~%%j,1!" neq "" set "len=%%j"
      )
      set /A len+=1
      echo !len!: !name!
   )
)

Antonio

pstein
Posts: 125
Joined: 09 Nov 2011 01:42

Re: List all files with filenames longer than 255 chars?

#9 Post by pstein » 01 Dec 2015 01:49

@aacini: Thank you, your first code seems to work fine.

But is there a way to replace the current fix length threshold 100 by a variable?

The following does NOT work:

Code: Select all

@echo off
setlocal EnableDelayedExpansion
set threshold=100
for /R H:\archive %%f in (*.*) do (
   set "name=%%f"
   if "!name:~!threshold!,1!" neq "" (
      for /L %%i in (:~!threshold!,1,500) do if "!name:~%%i,1!" neq "" set /A len=%%i+1
      echo !len!: !name!
   )
)

pstein
Posts: 125
Joined: 09 Nov 2011 01:42

Re: List all files with filenames longer than 255 chars?

#10 Post by pstein » 29 May 2016 13:47

I want to rever to the code from @Aacini below. It works.

However I need now a slight modification:

How can I find all filenames with a length above 100 chars BUT this time the prepended path is not added.

So the length calculation should be only for the filename(+extension)

How do I have to modify the following code?

Aacini wrote:

Code: Select all

@echo off
setlocal EnableDelayedExpansion

for /R H:\archive %%f in (*.*) do (
   set "name=%%f"
   if "!name:~100,1!" neq "" (
      for /L %%i in (100,1,500) do if "!name:~%%i,1!" neq "" set /A len=%%i+1
      echo !len!: !name!
   )
)

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: List all files with filenames longer than 255 chars?

#11 Post by foxidrive » 30 May 2016 00:01

Change this line

set "name=%%f"

to this, and try it. It only uses the filename.ext instead of the fully qualified pathname.

set "name=%%~nxf"

douglas.swehla
Posts: 75
Joined: 01 Jun 2016 09:25

Re: List all files with filenames longer than 255 chars?

#12 Post by douglas.swehla » 01 Jun 2016 15:53

pstein wrote:But is there a way to replace the current fix length threshold 100 by a variable?

The following does NOT work:

Code: Select all

@echo off
setlocal EnableDelayedExpansion
set threshold=100
for /R H:\archive %%f in (*.*) do (
   set "name=%%f"
   if "!name:~!threshold!,1!" neq "" (
      for /L %%i in (:~!threshold!,1,500) do if "!name:~%%i,1!" neq "" set /A len=%%i+1
      echo !len!: !name!
   )
)


In the IF statement, replace !threshold! with %threshold%.
  • You can't have nested variables of the same type (delayed or normal). The command interpreter will read !name:~!threshold!,1! as the variable !name:~!, followed by the string threshold, followed by the variable !,1!. The variables name:~ and ,1 are undefined, so the test will be read as if "threshold" neq "", which will always return true.
  • You can't nest delayed expansion variables within normal ones. Given the string %name:~!threshold!,1%, the command interpreter will try to expand the variable named name:~!threshold!,1, which is undefined. It will never get a chance to look at !threshold!, since it doesn't survive the first expansion.
  • You can nest normal variables within delayed expansion variables. On the initial "read" pass, the command interpreter will read in the string !name:~%threshold%,1!, and expand the normal variable to its value, so that the string is now !name:~100,1!. On the follow-up "execute" pass, the command interpreter will do the delayed expansion and convert !name:~100,1! to the 101st character of the file !name!, if such a character exists.

In the FOR /L loop, remove the colon and tilde from (:~!threshold!,1,500).
  • The range for the loop takes only integers.
  • Here, you can use either !threshold! or %threshold%. Generally, the reason to use delayed expansion within a loop is for nesting variables, as described above, or so that you can retrieve the newly created or changed value of a variable. Since threshold was created outside the loop, and it isn't being changed or incremented inside it, it's safe to use it either way.

Post Reply