DIR имена файлов, которые содержат расширения
Я просто пытался проверить директорию дампа для любых программ ZIP, таких как PeaZip, NanoZip и т. Д., И столкнулся со странной проблемой, с которой я сталкивался всего несколько раз раньше.
Я использовал следующую команду, чтобы получить список файлов, имена файлов которых содержат zip
(например, nanozip.zip
, peazip2.rar
, winzip-beta.exe
, так далее.):
dir *zip*
В этом списке перечислены все файлы, имена которых содержат zip
, но также все файлы с .zip
расширение (например, foobar.zip
).
Затем я попробовал следующее:
dir *zip*.*
Это дало те же результаты.
Кто-нибудь знает способ получить ожидаемые результаты? (Я знаю это for
может быть в состоянии сделать это, но вывод не будет правильным.)
8 ответов
проблема
Список всех файлов, которые имеют zip
в базовом имени (перед последней точкой, если таковая имеется) сложно из-за двух причин:
В Windows есть только два подстановочных знака:
*
а также?
,*
соответствует любому количеству символов (включая ноль).?
соответствует ровно одному символу (за исключением точки), если только это не последний символ шаблона, за которым следует точка, только другие символы подстановки или только другие символы подстановки, а затем точка.1В длинных именах файлов нет актуальных расширений. GUI может рассматривать все, что следует за последней точкой, как расширение файла, но это всего лишь соглашение.
Усугублять проблему,
.
имеет особое значение в командной строке. До LFN каждый файл имел расширение (хотя оно могло быть пустым). Следовательно,*.*
совпали все файлы, в то время как*
сопоставляются только файлы с пустым расширением.Чтобы поддерживать обратную совместимость,
.
игнорируется, если за ним следуют только символы подстановки и другие точки, за исключением случаев, когда точки соседствуют, и за ними следует по крайней мере один знак подстановки или если вообще нет символа подстановки и не более одной звездочки перед точкой.1
Примеры:
foo?.bar
будет соответствовать файлуfoo.bar
, ноfoo?bar
не будет соответствовать ниfoobar
ниfoo.bar
,*
,*.*
,*.*.
,*.*.*
а также**.
будет соответствовать всем файлам в любой данной папке, в то время как*.
,*..
а также*..*
не будет.
Временное решение
Если вы не используете бит архива для создания инкрементных резервных копий2, есть способ отобразить интересующие вас файлы (и только те), используя только DIR и команду ATTRIB.
шаги:
Сначала установите бит архива для всех файлов, которые содержат
zip
где-нибудь в их соответствующих именах файлов:ATTRIB +A *zip*
Теперь сбросьте бит архива на всех файлах с
zip
расширение:ATTRIB -A *.zip
Если вы хотите исключить файлы, соответствующие расширения которых заканчиваются на
zip
а также (например,ezip
), вместо этого используйте следующую команду:ATTRIB -A *.*zip
поскольку
*.*zip
будет также проверен на соответствие 8.3 именам файлов, это также будет соответствовать файлам, чьи соответствующие расширения начинаются сzip
(например,zipx
), если имена файлов 8.3 отсутствуют или не были изменены.Так как предыдущая команда сбросила бит архива на файлы типа
nanozip.zip
сбросьте те:ATTRIB +A *zip*.*zip
Теперь вы можете использовать
/AA
Переключатель команды DIR для отображения только файлов с установленным битом архива:DIR /AA *zip*
С /S
включите DIR и /S [/D]
включите ATTRIB, это работает даже для файлов в подкаталогах.
1 Это предназначено как список причуд, а не исчерпывающее объяснение поведения подстановочных знаков.
2 NTBackup в Windows XP, например, учитывает бит архива.
Если вы хотите "глазного яблока", используйте
dir /OE *zip*
который отсортирует выходные данные по расширению и может визуально игнорировать файлы с расширением.zip - все они будут сгруппированы вместе.
Для просмотра списка, массажа и т. Д. Отправьте вывод в файл:
dir /OE *zip*> myzip.txt
Пытаться:
реж * | findstr /i zip.*\.
пропустите / я, если вы хотите поиск с учетом регистра
Похоже на недельное решение выше:
dir | findstr /e zip.*.[a-z]*
Это должно найти все, что содержит "zip", затем любое количество символов, после которых следует "." и любое количество букв, за которыми следует конец имени файла. Я что-то пропустил?
Для тестирования это некоторые допустимые имена файлов, которые я использовал (т.е. те, которые имеют "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 автоматически означает, что совпадающее число файлов и каталогов будет неправильным (он покажет файлы и каталоги, изначально найденные dir, а не те, которые были окончательно отображены после фильтрации). Общий размер совпадающего файла, естественно, также будет неверным по той же причине, хотя свободные байты будут правильными, поскольку это не зависит от возвращаемых результатов.
Это может быть возможно при использовании замысловатого пакета или скрипта PowerShell, но на самом деле, в этот момент вы можете также написать свою собственную программу на C или аналогичную.
Не хороший, но рабочий..
dir | findstr ini..*
dots
используются в качестве регулярного выражения, означает любой символ и *
от 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
В наши дни нет веских причин использовать cmd.exe. PowerShell:
dir | ? {$_.BaseName.Contains('zip')}