5

Я просто пытался проверить директорию дампа для любых программ ZIP, таких как PeaZip, NanoZip и т.д., И столкнулся со странной проблемой, с которой я сталкивался всего несколько раз раньше.

Я использовал следующую команду для вывода списка файлов, имена файлов которых содержат zip (например, nanozip.zip , peazip2.rar , winzip-beta.exe и т.д.):

dir *zip*

В этом списке перечислены все файлы, имена файлов которых содержат zip , а также все файлы с расширением .zip (например, foobar.zip).

Затем я попробовал следующее:

dir *zip*.*

Это дало те же результаты.

Кто-нибудь знает способ получить ожидаемые результаты? (Я знаю, что for может быть в состоянии сделать это, но вывод не будет правильным.)

8 ответов8

2

проблема

Перечислить все файлы, у которых есть zip в базовом имени (перед последней точкой, если есть), сложно по двум причинам:

  • В Windows есть только два подстановочных знака: * и ? ,

    * соответствует любому количеству символов (включая ноль).

    ? соответствует ровно одному символу (кроме точки), если только это не последний символ шаблона, за которым следует точка, только другие символы подстановки или только другие символы подстановки, а затем точка. 1

  • В длинных именах файлов нет актуальных расширений. GUI может рассматривать все, что следует за последней точкой, как расширение файла, но это всего лишь соглашение.

    Что еще хуже . имеет особое значение в командной строке. До LFN каждый файл имел расширение (хотя оно могло быть пустым). Следовательно, *.* Соответствует всем файлам, а * соответствует только файлам с пустым расширением.

    Для поддержания обратной совместимости . игнорируется, если за ним следуют только символы подстановки и другие точки, за исключением случаев, когда точки соседствуют и сопровождаются хотя бы одним символом подстановки или если подстановочного знака нет вообще, и не более одной звездочки перед точкой. 1

Примеры:

  • foo?.bar будет соответствовать файлу foo.bar , но foo?bar не будет соответствовать ни foobar ни foo.bar .

  • * , *.* , *.*. *.*.* и **. будет соответствовать всем файлам в любой данной папке, в то время как *. , *.. и *..* не будет.

Временное решение

Если вы не используете бит архива для создания инкрементных резервных копий 2, есть способ отобразить интересующие вас файлы (и только те), используя только DIR и команду ATTRIB .

шаги:

  1. Во-первых, установите бит архива для всех файлов, которые содержат zip любом месте в соответствующих именах файлов:

    ATTRIB +A *zip*
    
  2. Теперь удалите бит архива для всех файлов с расширением zip :

    ATTRIB -A *.zip
    

    Если вы хотите исключить файлы, чьи соответствующие расширения заканчиваются также zip (например, ezip), используйте вместо этого следующую команду:

    ATTRIB -A *.*zip
    

    Так как *.*zip будет проверен на соответствие именам файлов 8.3, он также будет сопоставлять файлы, соответствующие расширения которых начинаются с zip (например, zipx), если только имена файлов 8.3 отсутствуют или не были изменены.

  3. Так как предыдущая команда сбросила бит архива для файлов, таких как nanozip.zip , сбросьте их:

    ATTRIB +A *zip*.*zip
    
  4. Теперь вы можете использовать ключ /AA команды DIR для отображения только файлов с установленным битом архива:

    DIR /AA *zip*
    

С параметром /S на DIR и /S [/D] на ATTRIB это работает даже для файлов в подкаталогах.


1 Это предназначено как список причуд, а не исчерпывающее объяснение поведения подстановочного знака.

2 NTBackup в Windows XP, например, учитывает бит архива.

0

Этот пакетный файл должен работать для вас.

Если вы запустите его без аргументов командной строки, он выдаст следующий список:

"dir *zip*.*"

но он будет отфильтровывать файлы, которые не содержат "zip" в части "name" имени файла (игнорирует расширение). Я предположил, что имя файла, содержащее "zip" в имени и расширении, является действительным совпадением, например:

somezipfile.zip

Если вы запустите его с аргументом (таким как txt или "txt" или "любой текст"), он будет делать то же самое, за исключением использования указанного аргумента вместо "zip".

Этот пакетный файл также будет отображать правильное количество файлов и итоговый размер файла.

Пожалуйста, дайте мне знать, если вы делаете не то, что вам нужно.

@echo off



set "zfind=%~1"
if "%zfind%."=="." set "zfind=zip"

set "zpattern=*%zfind%*.*"
set "zhold="
set zcount=0
set zgotbslash=0



for %%f in ("%zpattern%") do call :work1 "%%~nf" "%%~xf"



if NOT %zcount% EQU 0 goto :start2

rem no matches. look for something that "for sure" won't be found.
set zhold="<[nothing]>"
goto start2



:start2
set "zrandom=%random%.%random%.%random%.%random%.tmp"
if exist "%zrandom%" del "%zrandom%" >nul 2>&1
dir %zhold%>>"%zrandom%" 2>>&1



for /f "usebackq delims=" %%f in ("%zrandom%") do call :work2 "%%~f"



echo.
if exist "%zrandom%" del "%zrandom%" >nul 2>&1
goto :cleanexit



:work1

set "znam=%~1"
set "zext=%~2"



for /f "usebackq delims=" %%g in (`echo set "ztest=%%znam:%zfind%=%%"`) do %%g



rem if "%ztest%" equals "%znam%" then 
rem file "name" did NOT contain the search text.. skip it

if "%ztest%."=="%znam%." goto :work1skip
goto :work1match



:work1match
rem got a match

set zhold=%zhold% "%znam%%zext%"
set /A zcount=zcount+1
goto :EOF



:work1skip
rem skip this one

goto :EOF



:work2

set "zline=%~1"

rem if we already printed the " Directory of d:..." line then:
if %zgotbslash% EQU 1 goto :work2part2

rem looking for "\"
call :testbslash
if %zres% EQU 1 goto :work2gotbslash


echo %zline%
goto :EOF



:work2gotbslash
set zgotbslash=1
echo.
echo %zline%
echo.
goto :EOF



:work2part2
call :testbslash
if %zres% EQU 0 echo %zline%
goto :EOF



:testbslash
set zres=1
set "ztest=%zline:\=%"
if "%ztest%."=="%zline%." set zres=0
goto :EOF




:cleanexit

set "zcount="
set "zext="
set "zfind="
set "zgotbslash="
set "zhold="
set "zline="
set "znam="
set "zpattern="
set "zrandom="
set "zres="
set "ztest="
goto :EOF
0

Не хороший, но рабочий ..

dir | findstr ini..*

dots используются как регулярное выражение, означает любой символ и * от 0 до бесконечного времени

Единственным недостатком является то, что он не использует файлы без расширения.

0

Если вы хотите "глазного яблока", используйте

dir /OE * zip *

который отсортирует выходные данные по расширению и может визуально игнорировать файлы с расширением .zip - все они будут сгруппированы вместе.

Для просмотра списка, массажа и т.д. Отправьте вывод в файл:

dir /OE * zip *> myzip.txt

0

Похоже на недельное решение выше:

dir | findstr /e zip.*.[a-z]* 

Это должно найти все, что содержит "zip", затем любое количество символов, после которых следует «.» и любое количество букв, за которыми следует конец имени файла. Я что-то пропустил?

0

Пытаться:

реж * | findstr /i zip.*\.

пропустите / я, если вы хотите поиск с учетом регистра

0

Для тестирования это некоторые допустимые имена файлов, которые я использовал (то есть те, которые имеют "zip" где-то в имени файла, с расширением, не имеющим значения):

zip
has zip
has zip text
zip.doc
textzip.txt
File.zip.txt
File - zip text.zip
this file name haszipin it.txt

Неверные имена файлов:

noname
File.xzip
File.zipx
File.azipx
File.bxzip
File name.zip

Учитывая все вышеизложенное, а также отсутствие поддержки как "|" (или) и "+" (один или несколько) в findstr, я считаю, что то, что вы ищете, не может быть сделано с использованием только стандартных утилит Windows. Кроме того, в то время как другие выходные строки dir, такие как те, которые содержат "volume" или "directory" или "bytes", могут быть включены, использование find или findstr для фильтрации вывода dir автоматически означает, что совпадающее число файлов и каталогов будет неправильным ( он будет показывать файлы и каталоги реж изначально найдены, а не те , наконец , отображаются после фильтрации). Общий размер совпадающего файла, естественно, также будет неправильным по той же причине, хотя свободные байты будут правильными, поскольку это не зависит от возвращаемых результатов.

Это может быть возможно при использовании замысловатого пакета или скрипта PowerShell, но на самом деле, в этот момент вы можете также написать свою собственную программу на C или аналогичную.

-1

В наши дни нет веских причин использовать cmd.exe. PowerShell:

dir | ? {$_.BaseName.Contains('zip')}

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