Очень круто - я никогда не слышал об ADS раньше, и мне пришлось посмотреть, что это было.
Я не могу ручаться за то, насколько надежен ваш метод, но я вижу три способа, чтобы потенциально улучшить его.
1) Обычный файл может быть назван «$ DATA». Вы можете улучшить точность вашего фильтра, используя:
findstr /el :$DATA
2) Вы теряете информацию о пути, когда используете опцию DIR /R /S
и сохраняете только строки :$DATA
. Вот один неприятный вкладыш, который перечисляет размер файла и полный путь для всех ADS. Я перенаправляю stderr в nul, чтобы скрыть сообщения об ошибках из недоступных папок:
for /r %F in (.) do @(pushd "%F"&&(for /f "tokens=1*" %A in ('dir /r^|findstr /el :$DATA') do @echo %A %~fB)&popd)2>nul
3) ADS может быть присоединен к папке, а также к файлу. Предположим, существует следующая структура папок: C:\root\child\grandchild\
. Также предположим, что C:\root\child
имеет ADS с именем child:ads.txt
. Команда DIR /R /S
выведет ADS на следующие три уровня:
C:\root
перечислит child:ads.txt:$DATA
C:\root\child
будет в списке .:ads.txt:$DATA
C:\root\grandchild
grandchild отобразит список ..:ads.txt:$DATA
Требуется только первая запись. В цикле FOR /F размер %B
можно получить с помощью %~zB
, но это работает только для первого листинга; он расширяется до пустой строки для двух других. Это обеспечивает удобный и эффективный способ устранения нежелательных списков.
for /r %F in (.) do @(pushd "%F"&&(for /f "tokens=1*" %A in ('dir /r^|findstr /el :$DATA') do @if .%~zB neq . echo %A %~fB)&popd)2>nul
Окончательное решение выглядит намного лучше, как многострочный пакетный скрипт
@echo off
for /r %%F in (.) do (
pushd "%%F" &&(
for /f "tokens=1*" %%A in (
'dir /r^|findstr /el :$DATA'
) do if "%%~zB" neq "" echo %%~zB %%~fB
popd
)
)2>nul
Просто удалите %%A
(или %A
) из команды ECHO, если вам нужны только пути к файлам ADS без размеров файлов.