2017-06-13 2 views
0

J'essaie d'extraire tous les fichiers .txt et .pdf d'un emplacement défini, après une date fixe, et de les exporter vers csv. Cela fonctionne jusqu'à un certain point, mais quand je le nourris trop de données, il se bloque (comme le tri d'un serveur). Je suppose que la mémoire est pleine. Il doit également se reproduire comme il le fait actuellement. Si j'ajoute simplement -Append après Export-Csv il me dit que « L'objet en annexe ne dispose pas d'une propriété qui correspond à la colonne suivante: » et d'ajouter -Force mais si j'ajoute -Force après -Append il me dit "ne peut pas l'argument traiter parce que la valeur de l'argument "nom" n'est pas valide ". J'ai regardé la Cmdlet ForEach mais en vain. Vous cherchez un peu de sagesse si vous l'avez :)Exportation/Ajout de csv par lots de 1000 PowerShell

Param(
$startdate = (read-host -Prompt "Enter date"), 
$today  = (Get-Date),  
$RelPath = (read-host -Prompt "Enter filepath"), 
$RelFiles = "FullName" 
) 
Get-ChildItem -Path $RelPath"*.pdf", "*.txt" -Recurse| 
Where-Object { $_.LastWriteTime -gt $startdate -and $_.LastWriteTime -lt 
$today}|select -Property $RelFiles |sort -Property $RelFiles |export-csv 
C:\PowershellNewWork\New.csv 
+5

* quand je le nourrir trop de données, il se bloque * - avec quel message d'erreur? Oui '| sort' va stocker tout en mémoire, mais Windows utilise de l'espace disque comme mémoire virtuelle, donc à moins que vous ayez a) manuellement limité, ou b) manque d'espace disque, cela devrait simplement ralentir beaucoup plutôt que de planter . Aussi votre commande avec '-Path $ RelPath" *. Pdf "," * .txt' ne fait probablement pas ce que vous voulez.Il semblerait qu'il cherchera votre chemin choisi pour les PDF, et le chemin actuel pour les fichiers TXT. 'Get-ChildItem -Path $ RelPath -Include * .pdf, *. Txt -Recurse' – TessellatingHeckler

+0

Bravo pour l'aide :) J'aurais posté un message d'erreur mais il s'est seulement écrasé quand mon boss l'a lancé sur le serveur. Dans le futur, celui-ci enregistre –

+0

Bravo pour l'aide :) J'aurais posté un message d'erreur mais il s'est écrasé seulement quand mon boss l'a lancé sur le serveur. $ Startdate = (read-host -Prompt "Entrer la date"), $ aujourd'hui = (Date de Get-Date -DisplayHint), $ RelPath = (read-host -Prompt "Entrer le chemin du fichier"), $ RelFiles = " Nom complet " ) Get-ChildItem -Path $ RelPath -Inclut "* .pdf", "* .txt" -Recurse | Où-objet {$ _. LastWriteTime -gt $ startdate -et $ _. LastWriteTime -lt $ aujourd'hui} | sélectionnez -Property FullName | export-csv D: \ workexp \ Nouveau.csv –

Répondre

2

En supposant que vous avez juste besoin d'une colonne, conserver la mémoire et faire le script plus rapide:

  • IO.DirectoryInfo.EnumerateFiles est plus rapide que Get-ChildItem
  • Collections.Generic.SortedSet est plus rapide que Sort et ne duplique pas le contenu
  • Ecrivez le tableau sous forme de fichier texte au lieu de Export-Csv. Ajoutez manuellement doublequotes à chaque valeur
  • Au lieu de pipelining, utilisez une beaucoup plus rapide déclaration foreach et vérifie if simples

$files = [Collections.Generic.SortedSet[string]]@() 
foreach ($file in ([IO.DirectoryInfo]$RelPath).EnumerateFiles('*', 'AllDirectories') { 
    if (($file.Extension -eq '.pdf' -or $file.Extension -eq '.txt') -and 
     $file.LastWriteTime -gt $startdate -and $file.LastWriteTime -lt $today) 
    { 
     $files.Add('"' + $file.$RelFiles + '"') >$null 
    } 
} 
$UTF8noBOM = [Text.UTF8Encoding]$false 
[IO.File]::WriteAllLines('r:\out.csv', '"' + $RelFiles + '"', $UTF8noBOM) 
[IO.File]::AppendAllLines('r:\out.csv', $files, $UTF8noBOM) 

Testé dans PowerShell 5 sur un dossier très imbriquée avec 96K fichiers qui produit un CSV avec 2500 lignes:
2 secondes contre 15 secondes pour le code original,
Mémoire de 3 Mo contre 20 Mo utilisée.

+0

Ne pas avoir un PSv5 à tester en ce moment, mais au moins sur les anciennes versions '[void ] $ files.Add ('"' + $ file. $ RelFiles + '"') 'serait encore plus rapide (avec une marge très mince);) – whatever

+0

@whatever,' [void] 'a exactement la même vitesse que' > $ null' tel que mesuré dans la configuration mentionnée dans ma réponse. Ne soyez pas un "hax0r". – wOxxOm

+0

'[void]' est notablement plus rapide que dans un test synthétique non pratique comme 'foreach ($ i dans 1..1e6) {[void] $ i}' où il n'y a pas de code utile. En code réel, le temps nécessaire à l'exécution d'une fonction utile dépasse le temps de réacheminement ou de réacheminement nul de * ordres de grandeur *. – wOxxOm

0

communauté Grand, Voici le code final pour résoudre le problème

Param(
$startdate = (read-host -Prompt "Enter date"), 
$startdate2 =[datetime]::ParseExact("$startdate", "dd/MM/yy", $null), 
$today  = (Get-Date),  
$RelPath = (read-host -Prompt "Enter filepath"), 
$RelFiles = "FullName" 
) 
Get-ChildItem -Path $RelPath"*.pdf", "*.txt" -Recurse| 
Where-Object { $_.LastWriteTime -gt $startdate2 -and $_.LastWriteTime -lt $today}| 
select -Property $RelFiles |export-csv C:\PowershellNewWork\New.csv