Nomes de arquivos DIR que contêm extensões

5

Eu estava apenas tentando verificar um diretório de despejo para qualquer programa ZIP como PeaZip, NanoZip, etc. e me deparo com um problema estranho que eu tenho visto apenas algumas vezes antes.

Eu usei o comando a seguir para listar arquivos cujos nomes de arquivo contêm zip (por exemplo, nanozip.zip , peazip2.rar , winzip-beta.exe , etc.):

dir *zip*

Isso listou os arquivos cujos nomes de arquivo contêm zip , mas também todos os arquivos com uma extensão .zip (por exemplo, foobar.zip ).

Eu então tentei o seguinte:

dir *zip*.*

Isso deu os mesmos resultados.

Alguém sabe de uma maneira de obter os resultados esperados? (Eu sei que for pode ser capaz de fazer isso, mas a saída não estará correta.)

    
por Synetech 03.12.2012 / 18:32

8 respostas

2

Problema

Listar todos os arquivos que possuem zip no nome da base (antes do último ponto, se houver) é complicado por dois motivos:

  • O Windows possui apenas dois curingas: * e ? .

    * corresponde a qualquer número de caracteres (incluindo zero).

    ? corresponde exatamente a um caractere (exceto pelo ponto), a menos que seja o último caractere do padrão, seguido por um ponto, somente outros curingas ou apenas outros curingas e um ponto. 1

  • Não há extensão real em nomes extensos de arquivos. A GUI pode tratar tudo o que segue o último ponto como a extensão do arquivo, mas isso é apenas uma convenção.

    Para piorar, . tem um significado especial no prompt de comando. Antes do LFN, todo arquivo tinha uma extensão (embora pudesse estar vazio). Portanto, *.* corresponde a todos os arquivos, enquanto * corresponde apenas a arquivos com extensão vazia.

    Para manter alguma compatibilidade com versões anteriores, . é ignorado se for seguido apenas por curingas e outros pontos, exceto se os pontos forem adjacentes e seguidos por pelo menos um caractere curinga ou se não houver nenhum caractere curinga e no máximo um asterisco antes do ponto. 1

Exemplos:

  • foo?.bar corresponderá ao arquivo foo.bar , mas foo?bar não corresponderá a foobar nem foo.bar .

  • * , *.* , *.*. , *.*.* e **. corresponderão a todos os arquivos de uma determinada pasta, enquanto *. , *.. e *..* não corresponderão.

Solução alternativa

A menos que você esteja usando o arquivo para realizar backups incrementais 2 , há um maneira de exibir os arquivos que você está interessado (e somente aqueles), usando apenas DIR e o comando ATTRIB .

Etapas:

  1. Primeiro, defina o bit de arquivo em todos os arquivos que contenham zip em qualquer lugar em seus respectivos nomes de arquivo:

    ATTRIB +A *zip*
    
  2. Agora, desmarque o bit de arquivo em todos os arquivos com a extensão zip :

    ATTRIB -A *.zip
    

    Se você quiser excluir também arquivos cujas respectivas extensões terminam com zip (por exemplo, ezip ), use o seguinte comando:

    ATTRIB -A *.*zip
    

    Como *.*zip será testado em relação aos nomes de arquivo 8.3, isso também corresponderá aos arquivos cujas respectivas extensões começam com zip (por exemplo, zipx ), a menos que os nomes de arquivo 8.3 não estejam presentes ou tenham sido alterados .

  3. Como o comando anterior desabilitou o bit de arquivamento em arquivos como nanozip.zip , redefina-os:

    ATTRIB +A *zip*.*zip
    
  4. Agora, você pode usar a opção /AA do comando DIR para mostrar apenas arquivos com um bit de archive definido:

    DIR /AA *zip*
    

Com a opção /S no DIR e a opção /S [/D] no ATTRIB, isso até funciona para arquivos em subdiretórios.

1 Isso é uma lista de peculiaridades, em vez de uma explicação exaustiva sobre o comportamento de caractere curinga.

2 O NTBackup do Windows XP, por exemplo, respeita o bit de arquivo.

    
por 11.12.2012 / 05:39
0

Não é uma boa ideia, mas funciona uma.

dir | findstr ini..*

dots é usado como expressão regular, significa qualquer caractere e * de 0 a infinitas vezes

A única desvantagem é que ele não faz arquivos mach com a extensão.

    
por 03.12.2012 / 18:53
0

Se você está disposto a "olhar", use

dir /OE *zip*

que ordenará a saída por extensão e pode ignorar visualmente aqueles com uma extensão .zip - eles serão agrupados juntos.

Para uma lista, você pode examinar, massagear, etc. enviar a saída para o arquivo:

dir /OE *zip* > myzip.txt

    
por 03.12.2012 / 18:58
0

Tente:

dir * | findstr /i zip.*\.

omite o / i se quiser uma pesquisa sensível a maiúsculas

    
por 03.12.2012 / 19:45
0

Semelhante à solução da semana acima:

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

Este deve encontrar qualquer coisa que contenha "zip", seguido por qualquer número de caracteres, seguido por um "." e qualquer número de letras, seguido do final do nome do arquivo. Eu senti falta de mais alguma coisa?

    
por 03.12.2012 / 19:10
0

Para testes, estes são alguns nomes de arquivos válidos que eu usei (ou seja, aqueles que possuem "zip" em algum lugar no nome do arquivo, com extensão não importando):

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

Nomes de arquivo inválidos:

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

Dado todo o acima, e uma falta de apoio para ambos os "|" (ou) e "+" (um ou mais) em findstr , acredito que o que você está procurando não pode ser feito usando apenas utilitários Windows. Além disso, enquanto as outras linhas de saída dir como aquelas contendo "volume" ou "diretório" ou "bytes" podem ser incluídas, usando find ou findstr para filtrar a saída de dir automaticamente significa que a contagem de arquivos e diretórios correspondentes estará incorreta (mostrará os arquivos e diretórios dir originalmente encontrado, não os que são exibidos após a filtragem). O tamanho total do arquivo correspondente será naturalmente incorreto também pelo mesmo motivo, embora os bytes livres sejam corretos, pois isso não depende dos resultados retornados.

Isso pode ser possível usando um script em lotes ou PowerShell complicado, mas, na verdade, nesse momento você pode codificar seu próprio programa em C ou similar.

    
por 03.12.2012 / 20:51
0

Esse arquivo em lotes deve funcionar para você.

Se você executá-lo sem argumentos de linha de comando, ele fornecerá uma listagem como:

"dir *zip*.*"

mas filtrará os arquivos que não contêm "zip" na parte "nome" do nome do arquivo (ignora a extensão). Eu assumi que um nome de arquivo que contém "zip" no nome AND extension é uma correspondência válida, como:

somezipfile.zip

Se você executá-lo com um argumento (como txt ou "txt" ou "qualquer texto"), ele fará o mesmo, exceto usando o argumento especificado em vez de "zip".

Esse arquivo em lote também exibirá a contagem correta de arquivos e o resumo do tamanho do arquivo.

Por favor, deixe-me saber se não está fazendo o que você precisa.

@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
    
por 11.12.2012 / 08:14
-1

Não há bons motivos para usar cmd.exe nos dias de hoje. PowerShell:

dir | ? {$_.BaseName.Contains('zip')}
    
por 11.12.2012 / 08:30

Tags