List all files with filenames longer than 255 chars?
Moderator: DosItHelp
List all files with filenames longer than 255 chars?
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
(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
Re: List all files with filenames longer than 255 chars?
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
Re: List all files with filenames longer than 255 chars?
@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
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
Re: List all files with filenames longer than 255 chars?
I thought ROBOCOPY fixes that issue.
Re: List all files with filenames longer than 255 chars?
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.
Re: List all files with filenames longer than 255 chars?
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
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
Re: List all files with filenames longer than 255 chars?
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:
The method to get the length of the path can be changed by a more efficient one, like this:
Antonio
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
Re: List all files with filenames longer than 255 chars?
@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:
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!
)
)
Re: List all files with filenames longer than 255 chars?
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?
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!
)
)
Re: List all files with filenames longer than 255 chars?
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"
set "name=%%f"
to this, and try it. It only uses the filename.ext instead of the fully qualified pathname.
set "name=%%~nxf"
-
- Posts: 75
- Joined: 01 Jun 2016 09:25
Re: List all files with filenames longer than 255 chars?
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.