Comment puis-je faire de ce script PowerShell analyser de gros fichiers plus rapidement?
J'ai le texte suivant script PowerShell qui va analyser certains très gros fichier pour ETL fins. Pour commencer mon fichier de test est ~ 30 MO. Fichiers les plus grands autour de 200 MO sont attendus. J'ai donc quelques questions.
Le script ci-dessous fonctionne, mais il faut un temps très long processus même de 30 MO de fichier.
Script PowerShell:
$path = "E:\Documents\Projects\ESPS\Dev\DataFiles\DimProductionOrderOperation"
$infile = "14SEP11_ProdOrderOperations.txt"
$outfile = "PROCESSED_14SEP11_ProdOrderOperations.txt"
$array = @()
$content = gc $path$infile |
select -skip 4 |
where {$_ -match "[|].*[|].*"} |
foreach {$_ -replace "^[|]","" -replace "[|]$",""}
$header = $content[0]
$array = $content[0]
for ($i = 1; $i -le $content.length; $i+=1) {
if ($array[$i] -ne $content[0]) {$array += $content[$i]}
}
$array | out-file $path$outfile -encoding ASCII
DataFile Extrait:
---------------------------
|Data statistics|Number of|
|-------------------------|
|Records passed | 93,118|
---------------------------
02/14/2012 Production Operations and Confirmations 2
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Production Operations and Confirmations
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|ProductionOrderNumber|MaterialNumber |ModifiedDate|Plant|OperationRoutingNumber|WorkCenter|OperationStatus|IsActive| WbsElement|SequenceNumber|OperationNumber|OperationDescription |OperationQty|ConfirmedYieldQty|StandardValueLabor|ActualDirectLaborHrs|ActualContractorLaborHrs|ActualOvertimeLaborHrs|ConfirmationNumber|
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|180849518 |011255486L1 |02/08/2012 |2101 | 9901123118|56B30 |I9902 | |SOC10MA2302SOCJ31| |0140 |Operation 1 | 1 | 0 | 0.0 | | 499.990 | | 9908651250|
|180849518 |011255486L1 |02/08/2012 |2101 | 9901123118|56B30 |I9902 | |SOC10MA2302SOCJ31|14 |9916 |Operation 2 | 1 | 0 | 499.0 | | | | 9908532289|
|181993564 |011255486L1 |02/09/2012 |2101 | 9901288820|56B30 |I9902 | |SOC10MD2302SOCJ31|14 |9916 |Operation 1 | 1 | 0 | 499.0 | | 399.599 | | 9908498544|
|180885825 |011255486L1 |02/08/2012 |2101 | 9901162239|56B30 |I9902 | |SOC10MG2302SOCJ31| |0150 |Operation 3 | 1 | 0 | 0.0 | | 882.499 | | 9908099659|
|180885825 |011255486L1 |02/08/2012 |2101 | 9901162239|56B30 |I9902 | |SOC10MG2302SOCJ31|14 |9916 |Operation 4 | 1 | 0 | 544.0 | | | | 9908858514|
|181638583 |990104460I0 |02/10/2012 |2101 | 9902123289|56G99 |I9902 | |SOC11MAR105SOCJ31| |0160 |Operation 5 | 1 | 0 | 1,160.0 | | | | 9914295010|
|181681218 |990104460B0 |02/08/2012 |2101 | 9902180981|56G99 |I9902 | |SOC11MAR328SOCJ31|0 |9910 |Operation 6 | 1 | 0 | 916.0 | | | | 9914621885|
|181681036 |990104460I0 |02/09/2012 |2101 | 9902180289|56G99 |I9902 | |SOC11MAR108SOCJ31| |0180 |Operation 8 | 1 | 0 | 1.0 | | | | 9914619196|
|189938054 |011255486A2 |02/10/2012 |2101 | 9999206805|5AD99 |I9902 | |RS08MJ2305SOCJ31 | |0599 |Operation 8 | 1 | 0 | 0.0 | | | | 9901316289|
|181919894 |012984532A3 |02/10/2012 |2101 | 9902511433|A199399Z |I9902 | |SOC12MCB101SOCJ31|0 |9935 |Operation 9 | 1 | 0 | 0.5 | | | | 9916914233|
|181919894 |012984532A3 |02/10/2012 |2101 | 9902511433|A199399Z |I9902 | |SOC12MCB101SOCJ31|22 |9951 |Operation 10 | 1 | 0 | 68.080 | | | | 9916914224|
Une recherche pour "Obtenir le Contenu des fichiers volumineux" a été très utile. Voir rkeithhill.wordpress.com/2007/06/17/....
OriginalL'auteur shawno | 2012-02-24
Vous devez vous connecter pour publier un commentaire.
Votre script lit une ligne à la fois (et lents!) et magasins de presque la totalité du fichier en mémoire (en gros!).
Essayer ça (pas testé beaucoup):
C'est un compromis entre l'utilisation de la mémoire et de la vitesse. Le
-match
et-replace
les opérateurs de travailler sur un tableau, vous pourrez filtrer et remplacer l'ensemble d'un tableau à la fois sans avoir à foreach par le biais de chaque enregistrement. Le-readcount
va provoquer le fichier à lire en morceaux de $des dossiers de lots, de sorte que vous êtes essentiellement la lecture de 1000 enregistrements à la fois, de faire le match et de le remplacer sur ce lot en ajoutant le résultat de votre fichier de sortie. Puis il va revenir pour la prochaine 1000 enregistrements. L'augmentation de la taille de $lot doit accélérer, mais il va faire plus de mémoire. Réglez cette fonction de vos ressources.Merci. Je l'ai regardé à nouveau et fait un peu de tuning. Pas sûr de savoir comment beaucoup que va aider à la performance, mais si je suis en train de lire les docs droit, compilé regexes sont plus rapides, et la coulée de la variable [regex] les amène à être compilé.
C'est bon, mais j'ai aussi besoin de comparer chaque élément du tableau avec le premier élément (en-tête) et l'enlever si il y a un match - parce qu'il est répété dans tout le fichier. Cela semble être l'endroit où les choses s'enlisent dans le script. Avec votre approche comment puis-je le faire sans affecter de gC à une variable?
Avez-vous besoin d'inclure une copie de l'en-tête au début du fichier de sortie?
J'ai mis à jour le script. Il doit saisir la ligne d'en-tête du fichier, couper l'attaque et de fuite |, et de commencer une nouvelle $outfile en utilisant que pour l'en-tête de la boucle commence. À l'aide de [regex]::la fuite, il crée un nouveau regex qui ne littérale match de l'en-tête de ligne, puis une -notmatch sur qui a ajouté à l'-match-remplacer la chaîne de chute de personnes à l'intérieur de la boucle.
OriginalL'auteur mjolinor
La
Get-Content
applet de commande ne marche pas aussi bien qu'un StreamReader lorsque vous traitez avec des fichiers très volumineux. Vous pouvez lire un fichier ligne par ligne à l'aide d'un StreamReader comme ceci:Certaines comparaisons de performances:
Total Des Secondes: 49.4742533
Total Des Secondes: 27.666803
Get-Content
n' pas charger tout le fichier en mémoire, mais l'affectation du résultat à une variable. C'est un principe de conception important dans PowerShell - streaming par le biais d'un pipeline peut être efficace en terme de mémoire, même pour de très grands ensembles de données.Si la comparaison est d'étouffement, je me demande si le PC est d'avoir à la page/sortie des données de vérification de l'élément x à l'encontre de l'élément 0, car il ne peut pas tenir tout l'ensemble de la chaîne de caractères en mémoire -- si donc, $contenu[0] peut ne pas être une constante de temps de l'opération, même si sur un petit dataset il pourrait être supposé. Peut-être essayez de copier le contenu de $contenu[0] dans une nouvelle variable et comparer qu'au lieu de l'élément de tableau.
Juste point de. Généralement, une variable est affectée à la sortie de Get-Content. J'ai mis à jour ma réponse en fonction de vos suggestions. Merci.
richnak, merci pour ce commentaire - je n'avais pas considéré que, s'agissant de l'élément 0.
OriginalL'auteur Andy Arismendi
C'est presque un non-réponse...j'aime PowerShell...mais je ne vais pas l'utiliser pour analyser les fichiers journaux, en particulier les gros fichiers journaux. Utilisation de Microsoft Analyseur De Journal.
OriginalL'auteur Dexter Legaspi