2

Я хотел бы знать, разработал ли кто-нибудь эффективный способ для NT длины пакета вычислений в данной папке. Это необходимо для определения файлов и папок, которые не будут успешно архивироваться на оптические носители, которые продолжают применять ограничения пути в 260 символов, хотя NTFS теперь поддерживает длину пути до 32 767 символов.

Я использовал пакетный скрипт, который работает, выводя каждый полный путь к файлу, измеряя размер файла и вычитая 2, чтобы получить количество символов в пути. Это хорошо работает для небольшого количества файлов, но занимает много времени, чтобы закончить для большого количества файлов. В идеале я хотел бы что-то, что работает почти так же быстро, как сама команда 'dir'.

@ECHO OFF

SETLOCAL ENABLEDELAYEDEXPANSION

set Limit=%~1
echo Paths being found which exceed !Limit!
echo ======================================
type NUL > "!temp!\tabulator.txt"
FOR /F "tokens=1 delims=" %%A IN ('dir /o:-n /b /s') DO (
set Test=%%A
call set Test=%%Test:~%Limit%%%.
IF !Test! NEQ . (
type NUL > "!temp!\pathlengthdeterminationtemp.txt"
echo %%A > "!temp!\pathlengthdeterminationtemp.txt"
FOR /F "tokens=1 delims=" %%H IN ('dir /s /o /b "!temp!\pathlengthdeterminationtemp.txt"') DO set StrLen=%%~zH
del "!temp!\pathlengthdeterminationtemp.txt"
set /a StrLen=!StrLen!-2
echo !StrLen!,%%A>> "!temp!\tabulator.txt"
)
)

sort "!temp!\tabulator.txt" /O "!temp!\tabulator1.txt"
del "!temp!\tabulator.txt"
TYPE "!temp!\tabulator1.txt"
del "!temp!\tabulator1.txt" 

ENDLOCAL

4 ответа4

2

Чтобы проверить длину переменной среды, вы можете сделать что-то похожее на это:

set a=1234567890123

if [%a:~0,-12%]==[] (
    echo a is shorter than 13
) else (
    echo %a% is longer than 12
)

Выражение %a:~0,-12% возвращает все, кроме последних 12 символов переменной a .

Введите set /? чтобы получить детали.

Тем не менее, я не уверен, что это также работает под NT . Я проверил это как сценарий CMD под Windows 7 .

0

Вы можете отфильтровать вывод DIR программой, используя регулярное выражение.
findstr может сделать это, но, к сожалению, регулярное выражение очень ограничено и поддерживает только шаблоны поиска длиной до 254 символов.
Код может быть:

@echo off
setlocal enabledelayedexpansion
set "_LIMIT_=%~1"

set _PATTERN_=
for /l %%n in (1,1,%_LIMIT_%) do (set "_PATTERN_=!_PATTERN_!.")

dir /o:-n /b /s | findstr /r "/c:%_PATTERN_%"

Если вы не возражаете против использования сторонних программ, вы можете вместо этого использовать grep. Это очень просто:

@echo off
setlocal
set "_LIMIT_=%~1"

dir /o:-n /b /s | grep -E .{%_LIMIT_%}
0

Нет встроенной команды для определения длины строки в пакетном файле. Это обязательно включает в себя уродливые хаки, такие как запись в файл. Однако относительно легко проверить, превышает ли строка фиксированную длину, такую как ограничение в 260 символов. Следующий скрипт захватывает подстроку из 260 символов и проверяет равенство. Если обе переменные не совпадают, предполагается, что путь слишком длинный и напечатан.

@echo off
setlocal enabledelayedexpansion
for /F "tokens=1 delims=" %%i in ('dir /o:-n /b /s') do (
    set filename=%%i
    set part=!filename:~0,260!
    if !filename! NEQ !part! echo !filename!
)
0

Если я понимаю, вам может понадобиться эффективный счетчик строк? Итак, смотрите : _cnt_str_len выше, но я определенно не понимаю, тогда часть: IF !Test! NEQ . (

@ECHO OFF &&  SETLOCAL ENABLEDELAYEDEXPANSION

set Limit=%~1
echo Paths being found which exceed !Limit!
echo ======================================
type NUL > "!temp!\tabulator.txt"
FOR /F "tokens=1 delims=" %%A IN ('dir /o:-n /b /s') DO (
set Test=%%A
call :_cnt_str_len
echo/!Test! have len = !_cnt_str_len!
Set StrLen=!_cnt_str_len!
rem :: call set Test=%%Test:~%Limit%%%.
IF "!_cnt_str_len!" GEQ "!Limit!" (
type NUL > "!temp!\pathlengthdeterminationtemp.txt"
echo %%A > "!temp!\pathlengthdeterminationtemp.txt"
FOR /F "tokens=1 delims=" %%H IN ('dir /s /o /b "!temp!\pathlengthdeterminationtemp.txt"') DO set StrLen=%%~zH
del "!temp!\pathlengthdeterminationtemp.txt"
set /a StrLen=!StrLen!-2
echo !StrLen!,%%A>> "!temp!\tabulator.txt"
)
)

sort "!temp!\tabulator.txt" /O "!temp!\tabulator1.txt"
del "!temp!\tabulator.txt"
TYPE "!temp!\tabulator1.txt"
del "!temp!\tabulator1.txt" 

ENDLOCAL

goto :_end_of_file

:_cnt_str_len

if defined _cnt_str_len set _cnt_str_len=

for /f %%h in ('cmd /u /c set /p "=%Test:"= %"^<nul^|find /v /c ""') do (

     set _cnt_str_len=%%~h&& call set _cnt_str_len=!_cnt_str_len!

     exit /b 

)

:_end_of_file

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .