Existe alguma maneira de obter o shell do Windows cmd para expandir os caminhos curinga?

32

Ocasionalmente, a incapacidade do shell cmd de expandir os caminhos de curingas pode realmente ser um inconveniente. Eu tive que passar 100 arquivos em um diretório para um programa, e não pude digitar * .ext. Em vez disso, usei o 'ls' do mingw para despejar a lista em um arquivo, depois substituí as novas linhas por espaços, copiei e colei no cmd. Um pesadelo.

Eu suspeito que a resposta será não, mas alguém já lidou com isso ou inventou alguma maneira de tornar isso mais fácil?

    
por cemulate 12.08.2012 / 08:29

6 respostas

16

DOS e, consequentemente, o Windows ' cmd.exe , nunca suportou a expansão de curingas pelo shell. Sempre foi até o aplicativo fazer a expansão.

Isso significa que você sempre terá que encontrar outra rota se estiver usando um aplicativo que não suporta expansão. Você poderia:

  • Use um loop FOR para executar alguns comandos em todos os arquivos nos quais você tem interesse
  • Use dir /b > list.txt para usar o comando dir para executar a expansão e colocar a lista de arquivos em um arquivo de texto (você poderia usar algo como uma fórmula do Excel se estiver realmente desesperado para produzir uma lista de comandos para colar em cmd , ou você pode usar o Excel para transpor as células para que todos os nomes de arquivos estejam na mesma linha.)
por 12.08.2012 / 09:30
8

Basta usar o Powershell, que é pré-instalado no Windows 7. O Powershell é capaz de executar comandos cmd e entende curingas em qualquer lugar em um caminho.

Para iniciar o Powershell, basta digitar "powershell" na caixa de pesquisa do menu Iniciar e teclar enter.

Caso o aplicativo espere uma string com todos os nomes de arquivo, este é o script correto:

$delimiter = " "
[string]$files = $nothing ; ls *.txt | % { $files += $_.fullname + $delimiter } ; application.exe $files

Altere $delimiter = " " para $delimiter = "," se seu aplicativo espera uma lista separada por vírgulas de nomes de arquivos.

Explicação do código:

  • [string]$files = $nothing - cria uma variável vazia do tipo string
  • ; - é um separador para vários comandos, não um pipeline!
  • ls *.txt | % { $files += $_.fullname + $delimiter } - obtém uma lista de todos os arquivos de texto e cria uma string com todos os nomes de arquivos separados pelo delimitador
  • application.exe $files - chama o aplicativo e passa a lista de arquivos para ele

Você pode até procurar um padrão de arquivo recursivamente, adicionando -recurse a ls *.txt , então o código completo ficaria assim:

$delimiter = " "
[string]$files = $nothing ; ls *.txt -recurse | % { $files += $_.fullname + $delimiter } ; application.exe $files

Editar:
Para evitar irritações, ls e dir são aliases de Get-ChildItem e % é um alias para ForEach-Object . Eu mantenho meu código com aliases usados porque é mais curto.

EDIT 2018/04/25:
Em 2012, fui relativamente novo no PowerShell. É claro que existe uma maneira mais fácil, embora não seja tão fácil quanto a capacidade de expansão glob do unix / linux:

app.exe $(ls *.txt | % {$_.FullName})

Explicação:

  • $ () avaliará a expressão dentro dela primeiro e será substituído por ela com a saída dessa expressão (muito parecido com os backticks no bash)
  • ls *.txt obtém objetos FileInfo de todos os arquivos que correspondem ao glob %código%
  • porque o PowerShell é orientado a objetos, temos que produzir nome completo de cada objeto FileInfo. Simplesmente nomeando um atributo / propriedade no PowerShell, o exibe por padrão. *.txt faz isso para nós. % { $_.FileName } faz um loop sobre todos os elementos retornados por % e produz cada objeto FileName.
por 12.08.2012 / 14:00
6

Isso lhe dará uma lista e também a colocará na variável chamada expanded_list . Coloque-o no arquivo de lote e execute com myBatchFile name myPattern . Coloque o padrão entre aspas, se incluir espaços. Corresponde aos arquivos, sem dirs. Executar sem parâmetros corresponde a todos.

@echo off
set expanded_list=
for /f "tokens=*" %%F in ('dir /b /a:-d "%~1"') do call set expanded_list=%%expanded_list%% "%%F"

echo expanded_list is: 
echo %expanded_list%

Você pode então executar seu comando com my_command_exec %expanded_list%

AVISO! O tamanho máximo da variável cmd é de 8191 caracteres (XP em diante), portanto, é possível transbordá-lo! Você não pode contar com o utilitário para sempre dar uma lista completa. Por outro lado, o comprimento máximo da linha cmd também é 8191, portanto, você não poderá executá-lo de qualquer maneira.

    
por 12.08.2012 / 13:46
3

Isso funciona no cmd.exe

dir /b *.ext

ou

echo | dir /b *.ext
    
por 21.10.2014 / 17:31
1

Isso é antigo, mas com o subsistema Linux para windows, é bem comum ter o bash em seu PATH agora. Se for esse o caso, então isso pode fazer o truque para você:

bash -c 'cat *.txt'
    
por 30.08.2018 / 05:21
0

Note que isto está em Comentar aos cartazes em um tópico separado user619818 e styfle)

O DIR pode e permite pesquisar em todos os subdiretórios por arquivos que correspondam a um tipo específico.

Nota: O Diretório Raiz para verificar que todos os subdiretórios estão abaixo é assumido como "C: \ Meu Programa \ Root \", pois o autor não forneceu um nome de caminho sob o qual esses diretórios estão localizados

DIR /B /S "C:\My Program\Root\*.ext"

isso fornecerá os caminhos de arquivo completos e os nomes dos arquivos de origem.

se você quiser apenas nomes de arquivos, terá que fazer da seguinte maneira

FOR /F "Tokens=*" %A IN ('DIR /B /S "C:\My Program\Root\*.ext"') DO @( Echo.%~nxA )

então, supondo que você queira mover todos esses arquivos de "C: \ Meu Programa \ Root \ Sub Diretórios \ *. ext" para "D: \ Singlefolder \ *. ext", basta fazer isso:

FOR /F "Tokens=*" %A IN ('DIR /B /S "C:\My Program\Root\*.ext"') DO @( MOVE "%~A" "D:\Singlefolder\%~nxA" /Y )

Espero que ajude os outros no futuro. :)

    
por 10.02.2016 / 17:52