Estou tentando mover arquivos de uma pasta para outra no ambiente Windows usando o PowerShell. Tenho o processo de movimentação funcionando como preciso, mas gostaria de filtrar com base no último caractere do nome do arquivo. Por exemplo, DIR *1.zip
funciona bem no Windows Explore, mas $filesToMove = Get-ChildItem -Path $sourceFolder -File -Filter "*1.zip"
não. Nenhum arquivo é encontrado.
$filesToMove = Get-ChildItem -Path $sourceFolder -File -Filter "*.zip"
funciona bem. Alguma ideia de como isso pode ser feito?
Eu tentei vários filtros e padrões, mas não obtive sucesso. O que eu preciso é de uma solicitação como esta
$filesToMove = Get-ChildItem -Path $sourceFolder -File -Filter "*2.zip"
Isso só retorna FileNumber5932.zip de uma lista de arquivos.
Número do arquivo1796.zip
Número do arquivo 2021.zip
Número do arquivo 5932.zip
Número do arquivo 4369.zip
Número do arquivo 1615.zip
Imagino que o problema pode ser que o parâmetro -filter funcione de forma diferente do que você espera. O .zip funciona porque ele corresponde a todos os arquivos zip, mas quando você adiciona esse caractere extra, ele não está lendo como você e eu. Para isso, provavelmente usar expressões regulares ajudaria.
que tal tentar:
$filesToMove = Obter-ItemFilho -Caminho $pastaDeOrigem -Arquivo -Filtro “*.zip” | Onde-Objeto { $_.Nome -corresponder “1\.zip$” }
Deixe-me saber como isso funciona para você.
Infelizmente, o
-Filter
parâmetro está com bugs, conforme explicado nesta respostaUsar
-Include
em vez de-Filter
funciona , mas somente se você terminar o caminho na variável $sourceFolder com\*
, OU adicionar switch-Recurse
à chamada Get-ChildItem.Mas..:
-Include
é mais lento-Filter
porque só filtra depoisA outra solução alternativa é mostrada na resposta de Anthony Miranda para usar uma string mais genérica para o parâmetro Filter e anexar uma
Where-Object
cláusula para poder refinar ainda mais a filtragem nos nomes de arquivo. UsarWhere-Object
permite que você seja muito mais criativo ao especificar o que deseja obter, mas, como-Include
if, será mais lento que-Filter
.Todos eles (e provavelmente muitos mais) encontrarão o arquivo que você procura (na sua lista de exemplos
FileNumber2021.zip
)PS Ambos
[System.IO.Directory]::EnumerateFiles($sourceFolder, "*1.zip")
também[System.IO.Directory]::GetFiles($sourceFolder, "*1.zip")
produzem resultados errados.Há boas informações nas respostas existentes; deixe-me fornecer uma explicação mais detalhada e soluções alternativas:
Para contornar o comportamento inesperado
-Filter
sem precisar recorrer à pós- filtragem no pipeline por meio de umaWhere-Object
chamada, você tem duas opções:-Path
argumento (-File
omitido por brevidade):Se você quiser corresponder
.zip
a arquivos cujo nome base termina com qualquer dígito, use*[0-9].zip
-Include
em vez de-Filter
, e combine-o com-Depth 0
:Para procurar arquivos correspondentes recursivamente , ou seja, em toda a subárvore do diretório de destino, substitua
-Depth 0
por-Recurse
.Observação:
A necessidade infeliz e surpreendente de
-Depth 0
- que limita a enumeração a itens filhos imediatos , como é o comportamento padrão - é devida ao comportamento não intuitivo de-Include
e-Exclude
, conforme explicado nesta resposta .Embora
-Include
seja mais lento que-Filter
, porque filtra após o fato e não na fonte, ele tem vantagens distintas:-Filter
[035]
0
3
5
[0-5]
0
5
-Include
é ignorado se combinado com um argumento-LiteralPath
em vez de um-Path
; felizmente, esse problema foi corrigido no PowerShell (Core) 7 .O
-Filter
parâmetro não é interpretado pelo PowerShell, mas sim por uma chamada de sistema, conforme detalhado na resposta vinculada à resposta de Theo.O "dialeto" curinga que
-Filter
suporta não é apenas mais limitado em seus recursos, como observado, mas também tem peculiaridades herdadas para fins de compatibilidade com versões anteriores , conforme resumido nesta resposta .Na verdade, é uma dessas peculiaridades herdadas que causa o comportamento inesperado no seu caso: o
-Filter
padrão também é comparado aos nomes de arquivo curtos (8.3) , o que pode causar falsos positivos .-Filter *2.zip
pode - surpreendentemente - corresponder a um arquivo nomeadoFileNumber2021.zip
também, por exemplo, mesmo que claramente não termine em2.zip
. Isso acontece se seu nome de arquivo curto for algo comoFILENU~2.ZIP
;~1
,~2
, ... sufixos de nome base em nomes de arquivo curtos são artefatos do algoritmo de encurtamento e não estão relacionados ao nome de arquivo longo original. [1][1] A maneira mais simples de visualizar nomes curtos de arquivos junto com seus originais é executar algo como
cmd /c dir /x *.zip
Para abordagens que permitem processamento programático subsequente, consulte esta resposta .