O comando FOR não pode ver arquivos ocultos

6

Estou lutando com um dos erros mais frustrantes que já vi.

Descrição do bug:

  O forcomando do interpretador de comandos não pode ver arquivos ocultos.

Etapas de reprodução:

  1. Crie um diretório temporário
  2. Crie alguns arquivos
  3. Atribua uma variedade de atributos aos arquivos (incluindo ocultos)
  4. Use um comando como for %i in (*) do echo "%i"

Resultados esperados:

   Todos os arquivos são processados ​​no forloop por padrão ou através de uma opção.

Resultados reais:

  • Arquivos com qualquer atributo diferente de oculto são processados; arquivos sinalizados como ocultos são ignorados
  • Não há opção para o forcomando permitir processar arquivos ocultos

Implicações:

   Não há como processar todos os arquivos no prompt de comando.

Pergunta, questão:

   Como diabos os arquivos ocultos podem ser processados ​​no prompt de comando ou nos arquivos em lotes (pelo menos no Windows, se não no DOS)?

Synetech
fonte

Respostas:

5

Você poderia usar em forfilesvez de for.

A sintaxe é bem diferente, mas possui mais funcionalidades (por exemplo, método para acessar nativamente o nome do arquivo, a extensão, o tamanho do arquivo e o carimbo de data e hora) e processa todos os arquivos por padrão.

Por exemplo, em vez de

for %i in (*) do echo "%i"

você usaria

forfiles /c "cmd /c echo @file"

ou simplesmente

forfiles

desde "cmd /c echo @file"é o valor padrão para a opção de comando.

Dennis
fonte
Não é ruim. Ele usa uma sintaxe diferente e não está disponível no XP, mas é bom ter uma opção. (Na verdade, considerei uma porta Unix, mas, embora ls.exeseja útil, o forcomando é incorporado ao shell como no Windows. Suponho que alguém possa usar uma porta shell do Unix, mas esse não seria o prompt de comando do Windows.)
Synetech
Você pode canalizar a saída lspara xargsou simplesmente usar find. Ambos estão disponíveis para Windows.
Dennis
Hmm, sugestão interessante. O problema é que a execução de comandos externos como esse afetaria severamente o desempenho, especialmente quando há muitos arquivos / pastas (pelo menos em comparação com o forcomando interno).
Synetech
4

Aqui está uma solução alternativa (feia, desagradável, não ideal) para arquivos:

for /f "tokens=* delims=" %i in ('dir /b/a-d *') do echo "%i"

E uma versão para pastas (análoga a for /d…):

for /f "tokens=* delims=" %i in ('dir /b/ad  *') do echo "%i"

E uma versão para ambos (sem foranalógico, portanto, isso é um benefício):

for /f "tokens=* delims=" %i in ('dir /b/a   *') do echo "%i"


Versão recursiva para arquivos ( for… /r):

for /f "tokens=* delims=" %i in ('dir /b/s/a-d *') do echo "%i"

E pastas ( for /r /d…):

for /f "tokens=* delims=" %i in ('dir /b/s/ad  *') do echo "%i"

E ambos

for /f "tokens=* delims=" %i in ('dir /b/s/a   *') do echo "%i"



Isso funciona mais ou menos, mas definitivamente tem seus problemas (especialmente para grandes conjuntos de arquivos ou pastas). Espero que exista uma solução melhor ou a Microsoft possa corrigir / melhorar isso em um patch.

Synetech
fonte
2
Com tokens=*você, você pode omitir a delims=opção, e o *é redundante. Também dir /b/alistará diretórios e arquivos. Se você deseja apenas arquivos, precisa dir /b/a:-d. E como esse comportamento da linha de comando do Windows não mudou em 20 anos, provavelmente não vai mudar agora. Não gosta disso? Use VBScript ou PowerShell.
Ansgar Wiechers
@AnsgarWiechers, obrigado pelas dicas. Normalmente, não uso /foutra coisa senão para processar as linhas em um arquivo de texto (por exemplo, for /f "delims=" %i in (list.txt)…), por isso não conheço bem as opções extras. Você está certo em /alistar diretórios; Não sei por que meu teste anterior não os listou.
Synetech
@ Synetech, hmm, melhorei a resposta e uma votação foi anulada. Eu acho que isso vai me aprender a melhorar as coisas a partir de agora. sigh
Synetech
Eu só tive que recorrer a isso para um novo arquivo em lotes que escrevi e, para ser sincero, não foi tão ruim assim. Ele funciona bem o suficiente e era simples de lembrar e usar (deixei as opções tokense delimstotalmente excluídas para este). Por enquanto, vou aceitar isso porque ele mantém a forsintaxe, então nada precisa ser reescrito e "simplesmente funciona".
Synetech
Eu tenho usado o /fswitch para usar muito um comando para a expressão de loop nos últimos meses e, para ser sincero, estou realmente me acostumando. Ele ainda tem a desvantagem de que deve primeiro enumerar todos os arquivos / pastas para criar uma lista antes mesmo de iniciar o comando, mas também possui alguns benefícios como: usar dirpara acessar arquivos / pastas ocultos / do sistema; criar a lista antes do processamento; itens de processamento que são modificados; um forloop regular enumera in situ, para que ele possa inserir um loop infinito, pois os objetos modificados podem aparecer como novos a serem (re) processados.
Synetech