arquivos do filtro PowerShell por data no nome

2

Eu tenho muitos arquivos com nomes diferentes por dia. Como posso filtrá-los pela data em seu nome?

Por exemplo:

app_20130505.log
app_20130506.log
app_20130507.log
app_20130508.log
app_20130509.log

E meu snippet de código:

$RetainedDays = 7
$FileNameRegex = "\w+_(\d+)\.\w+"
$ArchiveBoundary = $(Get-Date -Format yyyyMMdd) - $RetainedDays
$ProcessFiles = Get-ChildItem -Path $RootPath -Recurse |
    Where-Object { $_.Name -match $FileNameRegex }

Eu tenho o filtro regex para ele: \w+_(\d+)\.\w+ , que me retorna a data na variável $ Matches, mas como posso combiná-los e recuperar a lista de arquivos com esses arquivos com mais de 7 dias? / p>     

por gazsiazasz 09.05.2013 / 16:38

3 respostas

1

Eu percebo que esta é uma pergunta de 4 anos de idade neste momento. Mas imaginei adicionar uma nova resposta, uma vez que atualmente não há outras respostas aprovadas.

A maneira como eu faço isso é analisar a data em um objeto DateTime real a partir do nome do arquivo. Então você pode usar comparações de datas normais em vez de comparações de strings. A maneira mais comum de fazer isso é usar uma propriedade calculada como parte de uma instrução Select-Object . No exemplo abaixo, adicionamos uma propriedade calculada chamada ParsedDate à saída existente.

$RetainedDays = 7
$FileNameRegex = "\w+_(\d+)\.\w+"
$culture = [System.Globalization.CultureInfo]::InvariantCulture
$ProcessFiles = Get-ChildItem -Path $RootPath -Recurse | 
  Select-Object *,@{
    L='ParsedDate';
    E={ if ($_.Name -match $FileNameRegex) { 
      $strDate = $matches[1];
      [DateTime]::ParseExact($strDate,"yyyyMMdd",$culture)
    }
  }
} | Where { $_.ParsedDate -lt (Get-Date).AddDays(-$RetainedDays) }

A expressão regular, na verdade, torna as coisas mais complicadas do que deveriam ser. Se todos os seus arquivos tiverem exatamente o mesmo padrão de nomenclatura de app_ < DATA > .log , você poderá ignorar o Regex e simplificar permitindo que ParseExact faça todo o trabalho dessa maneira. Você só precisa escapar dos caracteres literais na string de formato, envolvendo-os com aspas simples.

$RetainedDays = 7
$culture = [System.Globalization.CultureInfo]::InvariantCulture
$ProcessFiles = Get-ChildItem -Path $RootPath -Recurse | Select FullName,@{
  L='ParsedDate';
  E={ [DateTime]::ParseExact($_.Name,"'app_'yyyyMMdd'.log'",$culture) }
} | Where { $_.ParsedDate -lt (Get-Date).AddDays(-$RetainedDays) }

Tecnicamente falando, você também pode fazer a análise de data dentro da cláusula Where e pular a cláusula Select intermediária. Mas vou deixar isso como um exercício para o leitor.

    
por 05.04.2017 / 19:55
0

Não é muito legal, mas funciona! :)

$RetainedDays = 14

$ArchiveBoundary = (Get-Date).AddDays(-$RetainedDays).ToString('yyyyMMdd')

$ProcessFiles = Get-ChildItem -Path $RootPath -Recurse |
    Where-Object { ($_.BaseName -split '_|\.')[1] -lt $ArchiveBoundary }
    
por 10.05.2013 / 17:33
0

Veja se isso ajuda a aproximar você do que está tentando fazer.

$RootPath = "C:\temp"
$ProcessFiles = @()
$RetainedDays = 7
$Today = get-date -format yyyyMMdd
$FileNameRegex  = "\w+_(\d+)\.\w+"
foreach ($File in Get-ChildItem -Path $RootPath) {
   $match = [regex]::matches($File, $FileNameRegex )
   $FileNameDate = $match[0].Groups[1].Value
   if (($Today - $FileNameDate) -ge $RetainedDays) { $ProcessFiles += $File }
}
$ProcessFiles
    
por 09.05.2013 / 22:28