
Я знаю, что проводник Windows может раскрашивать состояние сжатия NTFS файла как в обычном режиме, так и в режиме поиска.
Как можно конкретно отфильтровать/поиск файлов, сжатых или несжатых на уровне NTFS?
Предпочтительно решение, работающее в Windows XP и выше (существует довольно много устройств, для которых не существует драйверов для Vista и выше).
Поскольку Windows Search слишком нагружает процессор, мне бы хотелось найти решение и без него.
решение1
Интерфейс командной строки
Windows XP не предоставляет возможности выводить список сжатых файлов из коробки, и даже расширенные методы поиска не предназначены для таких задач. Командная строка приходит на помощь:
cd /d "C:\Some folder"
compact | findstr /c:" 1 C"
Команда cd
просто используется для перехода в целевой каталог. Когда команда compact
запускается без параметров, она выводит список всех файлов вместе с подробностями их сжатия, если таковые имеются. Затем вывод можно отфильтровать, перенаправив его в findstr
. Что бы это ни стоило, этот метод должен работать даже в Windows 2000.
Тем не менее, вывод довольно многословен. Чтобы убрать лишнюю информацию, требуется еще немного работы:
for /f "tokens=9,*" %A in ('"compact | findstr /c:" 1 C" "') do @dir /b "%A*%B" 2>nul
Команда выше отобразит только сжатые имена файлов. Команда dir
поможет проверить имена файлов, чтобы избежать ложных срабатываний (например, содержащих строку 1 C
в своем имени).
Дополнительные параметры, которые вы можете использовать:
/s
Применяет команду ко всем подпапкам./a
Отображает скрытые или системные файлы.
Обратите внимание, что эти параметры следует использовать как для команд , так compact
и dir
для команд , если это необходимо.
Чтобы вывести список несжатых файлов, можно использовать /v
параметр команды findstr
для обратного фильтра и изменить tokens
значение на 8
(это связано с тем, что несжатые файлы не имеют маркера C
, который влияет на строкутокенизация).
дальнейшее чтение
Расширенный синтаксис запроса
Запросы Windows Search определяются с помощью расширенного синтаксиса запросов (AQS), который поддерживает не только простой текстовый поиск, но и предоставляет расширенные операции запросов на основе свойств.
AQS впервые был представлен в Windows Desktop Search, который впоследствии был улучшен и интегрирован в Windows Vista какПоиск Windows. Вам нужноустановить его отдельнов более ранних операционных системах.
Следующий запрос выведет список всех файлов, которые имеют установленный атрибут архива и сжаты. Это работает в Windows XP, Vista и 7. Это также должно работать в Windows 8.x, хотя я не проверял.
System.FileAttributes:(2080)
В английских локалях вы также можете использовать:
attributes:(2080)
Вот список наиболее полезных значений:
FILE_ATTRIBUTE_READONLY = 1
FILE_ATTRIBUTE_HIDDEN = 2
FILE_ATTRIBUTE_SYSTEM = 4
FILE_ATTRIBUTE_ARCHIVE = 32
FILE_ATTRIBUTE_COMPRESSED = 2048
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 8192
В приведенном выше примере я объединил FILE_ATTRIBUTE_ARCHIVE
и FILE_ATTRIBUTE_COMPRESSED
: 32 + 2048 = 2080
.
Вы можете искать любые комбинации, используя логический OR
оператор. Например, для поиска сжатых файлов, которые либо доступны только для чтения, либо нет:
System.FileAttributes:(2080 OR 2081)
Чтобы инвертировать результаты поиска, можно использовать NOT
оператор:
System.FileAttributes:NOT(2080 OR 2081)
дальнейшее чтение
решение2
и31415опубликовалхорошее решение для Windows Explorerкоторый работает по крайней мере в Windows 7 и выше (возможно, в Vista, проверю позже).
Поэтому для старых версий Windows, таких как XP и 2003, я искал решение командной строки, которое могло бы генерировать список сжатых или несжатых файлов.
Compact
: хорошо, но вывод сложно анализировать
Первой идеей было использованиекомпактный, который поставляется вместе с Windows.
И действительно, он может выводить список файлов (заключайте параметры в двойные кавычки, если они содержат пробелы):
compact [filemask] /a /s:[directoryname]
Формат удобен для чтения человеком, но непрост для анализа.
FindCompressed имеет ошибку с длинными именами путей, выдавая такие списки:
C:\Program Files\VMware\Infrastructure\Virtual Infrastructure Client\Help\en\DRS41\wwhelp\wwhimpl\common\htmlinit3.htm
C:\Program Files\VMware\Infrastructure\Virtual Infrastructure Client\Help\en\DRS41\wwhelp\wwhimpl\common\htmlpagenav.htm
...
C:\Program Files\VMware\Infrastructure\Virtual Infrastructure Client\Help\en\DRS41\wwhelp\wwhimpl\common\html\imagessplash.jpg
C:\Program Files\VMware\Infrastructure\Virtual Infrastructure Client\Help\en\DRS41\wwhelp\wwhimpl\common\imagestoolsbg.gif
...
C:\Program Files\VMware\Infrastructure\Virtual Infrastructure Client\Help\en\DRS41\wwhelp\wwhimpl\common\scriptsunidata.js
Поэтому он вырезает части файлов или каталогов, если их имена становятся слишком длинными.
# FindCompressed
: отлично, первую/последнюю строку вывода нужно убрать
Exodus Development написала инструмент командной строкиНайтиСжатый. Без параметров он находит сжатые файлы. С -su
параметром он находит несжатые файлы. Заключите [directoryname]
в двойные кавычки, если он содержит пробелы.
FindCompressed.exe -su [имя_каталога]
FindCompressed
имеет один недостаток: вывод всегда начинается с этой строки, где # — это [имя_каталога]:
Recursive search of compact #.
и заканчивается такой строкой:
Found # uncompressed files in # items examined.
Строки между ними содержат полный путь к несжатому или сжатому имени файла.
Это легко проанализировать.
решение3
Так как компактный показывает a C
в фиксированной позиции:
134217728 : 0 = 1.0 a 1 C BigFile.Dummy
123456789012345678901234567890123
= 33-я позиция указывает, сжат ли он NTFS.
Поскольку все сжатые файлы перечислены в списке compact с буквой C в 33-м символе (по крайней мере там, где я его запускаю, возможно, в других языках все по-другому), возможно, эта команда может помочь:
compact /A | findstr /R ^................................C
/R indicates that the following is a regular expression ^ is to indicate look from beggining of line The 32 dots for ignoring 32st charaters of the line Then the C to indicate must look for a C at the 33th position, that indicates it is NTFS compressed
Он выводит список всех файлов, а затем фильтрует их C
по 33-й позиции от начала строки.
Если вам нужна рекурсия, используйте цикл for, который выводит список всех каталогов и запускает эту команду для каждого из них, как в этом большом примере команды (если ее ввести непосредственно в командной строке):
(CD "C:\YourBaseDir\" && ECHO Listing NTFS compressed files and folders: && (compact /A /I | findstr /R ^................................C) && for /F "delims=" %a in ('DIR /AD/B/S') do @(CD "%a" && ECHO Listing NTFS compressed files and folders on: "%a" && (compact /A /I | findstr /R ^................................C)) & CD "C:\YourBaseDir\")
Если вы поместите команду в BATCH-файл, то %a
необходимо удвоить %
, поэтому все должно быть примерно так (все в одной большой строке):
(CD "C:\YourBaseDir\" && ECHO Listing NTFS compressed files and folders: && (compact /A /I | findstr /R ^................................C) && for /F "delims=" %%a in ('DIR /AD/B/S') do @(CD "%%a" && ECHO Listing NTFS compressed files and folders on: "%%a" && (compact /A /I | findstr /R ^................................C)) && CD "C:\YourBaseDir\")
Или для лучшего чтения в BATCH-файле:
@ECHO OFF
CD "C:\YourBaseDir\"
ECHO Listing NTFS compressed files and folders:
compact /A /I | findstr /R ^................................C
for /F "delims=" %%a in ('DIR /AD/B/S') do @(
CD "%%a"
ECHO Listing NTFS compressed files and folders on: "%%a"
compact /A /I | findstr /R ^................................C
)
CD "C:\YourBaseDir\"
Предупреждение: Compact также покажет сжатые папки, чтобы избежать этого, необходимо использовать двойной for.
Результат такой:
Listing NTFS compressed files and folders:
0 : 0 = 1.0 a 1 C a
134217728 : 0 = 1.0 a 1 C BigFile.Dummy
Listing NTFS compressed files and folders on: "D:\Temp\a"
0 : 0 = 1.0 a 1 C b
134217728 : 0 = 1.0 a 1 C Other.Dummy
Listing NTFS compressed files and folders on: "D:\Temp\a\b"
134217728 : 0 = 1.0 a 1 C Another.Dummy
Надеюсь, это поможет. Он основан на findstr, допускающем регулярные выражения, поэтому, пожалуйста, адаптируйте регулярное выражение к вашей версии ОС и языку.
Это делается для отображения только файлов (не папок) в списке результатов (внутри BATCH-файла с хорошим чтением):
@ECHO OFF
CD "D:\YourBaseDir\"
ECHO Listing NTFS compressed files:
for /F "delims=" %%a in ('DIR /A-D/B') do @(
compact /A /I "%%a" | findstr /R ^................................C
)
for /F "delims=" %%a in ('DIR /AD/B/S') do @(
for /F "delims=" %%b in ('DIR /A-D/B "%%a"') do @(
ECHO Listing NTFS compressed files on: "%%a\"
compact /A /I "%%a\%%b" | findstr /R ^................................C
)
)
Хитрость, позволяющая не показывать папки, заключается в использовании специального оператора FOR для обработки только /A-D
параметра files в FOR
; за счет вызова compact/findstr для каждого отдельного файла.
И, пожалуйста, обратите внимание, что эта команда не CD
переходит в каталог... она передает полный путь к файлу для сжатия в качестве параметра... предупреждение о длинных путях!!!
Результат будет таким (папки не показаны):
Listing NTFS compressed files:
134217728 : 0 = 1.0 a 1 C BigFile.Dummy
Listing NTFS compressed files on: "D:\Temp\a\"
134217728 : 0 = 1.0 a 1 C Other.Dummy
Listing NTFS compressed files on: "D:\Temp\a\b\"
134217728 : 0 = 1.0 a 1 C Another.Dummy
Его также можно улучшить (как и все в этом мире), используя sed
(из GNU для Windows) функцию, которая позволяет вырезать часть имени файла из пары compact/findstr, а также ECHO, которая объединяет путь и результат sed
.
Надеюсь, это поможет в выполнении задачи.