Question
Découper fichier texte trop long (+65335 lignes)
- Bredin Samuel
- Auteur du sujet
- Hors Ligne
- Membre senior
-
- Messages : 52
- Remerciements reçus 0
Votre avis sur une fonction.
Et si elle convient, elle pourra être utile à quelqu'un.
Il m'arrive d'avoir des demandes pour découper des fichiers *.csv devenus trop grand (plus de 65335 lignes).
J'ai d'abord créer une première fonction en 10 min :
[code:1]Function Split-File ($Fichier,$NbLigne) {
$objFile = gi $Fichier
$NomFichier = ($objFile.Fullname).Replace($objFile.Extension, '')
gc $Fichier -ReadCount 1 |`
% -Begin {
$i=0
$j=1
} -Process {
$i++
$zero = '_00'
if ($i % $NbLigne -eq 0) {$j++}
if ($j -ge 10 -and $j -lt 100) {$zero = '_0'}
elseif ($j -ge 100) {$zero = '_'}
$FichierFinal = $NomFichier + $zero + $j + $objFile.Extension
$_ | Out-File -filePath $FichierFinal -Append
}
}[/code:1]
Mais elle n'a jamais voulu fonctionner. (sur un fichier de 500 mo)
Pas vraiment le temps de chercher plus en détails.
J'ai fini par celle ci :
[code:1]Function Split-File ($Fichier,$NbLigne) {
$objFile = gi $Fichier
$NomFichier = ($objFile.Fullname).Replace($objFile.Extension, '')
gc $Fichier -ReadCount 1 |`
% -Begin {
$i=0
$j=1
$zero = '_00'
$tab = @()
} -Process {
$i++
$tab += $_
if ($i % $NbLigne -eq 0) {
if ($j -ge 10 -and $j -lt 100) {$zero = '_0'}
elseif ($j -ge 100) {$zero = '_'}
$FichierFinal = $NomFichier + $zero + $j + $objFile.Extension
$tab | Out-File -filePath $FichierFinal
$tab = @()
$j++
}
} -End {
$FichierFinal = $NomFichier + $zero + $j + $objFile.Extension
$tab | Out-File -filePath $FichierFinal
}
}[/code:1]
Finalement cette fonction va perdurer.
Auriez-vous des suggestions ?<br><br>Message édité par: Arnaud, à: 4/02/09 00:06
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Hors Ligne
- Modérateur
-
- Messages : 6311
- Remerciements reçus 68
utilise une collection et pas un tableau, le recyclage de la mémoire sera meilleur :
[code:1]
$Collections=New-Object \"System.Collections.Generic.List``1[System.String]\"
# Ou $Collections=New-object System.Collections.Specialized.StringCollection[/code:1]
Utilise une chaîne de formatage au lieu du test
[code:1]
#Leading zero
\"_{0:d3}\" -f 10
$FichierFinal = \"{0}_{1:d3}{2}\" -F $NomFichier,$j,$objFile.Extension[/code:1]
Ce qui donne :
[code:1]
Function Split-File ($Fichier,$NbLigne) {
$objFile = gi $Fichier
$NomFichier = ($objFile.Fullname).Replace($objFile.Extension, '')
gc $Fichier -ReadCount 1 |`
% -Begin {
$i=0
$j=1
$Collections=New-Object \"System.Collections.Generic.List``1[System.String]\"
} -Process {
$i++
[void]$Collections.Add($_)
if ($i % $NbLigne -eq 0) {
$FichierFinal = \"{0}_{1:d3}{2}\" -F $NomFichier,$j,$objFile.Extension
$Collections.GetEnumerator() | Out-File -filePath $FichierFinal
$Collections.Clear()
$j++
}
} -End {
$FichierFinal = \"{0}_{1:d3}{2}\" -F $NomFichier,$j,$objFile.Extension
if ($Collections.Count -gt 0)
{$Collections.ToString()| Out-File -filePath $FichierFinal}
}
}[/code:1]
A vérifier.
Tu peux peut-être utiliser Readcount=100 couplé à la méthode Collection.Addrange($_).
Ce sera peut-être plus rapide, je te laisse tester
ps :
On peut changer l'extension ainsi
[code:1][System.IO.Path]::ChangeExtension($F.FullName,\"\"«»)[/code:1]
Mais le point précédent l'extension n'est pas effacé...
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Bredin Samuel
- Auteur du sujet
- Hors Ligne
- Membre senior
-
- Messages : 52
- Remerciements reçus 0
Un grand merci.
Tu avais complètement raison.
Les collections sont beaucoup mieux.
Ma fonction d'origine 1h et 17 min.
La tienne 3 min 52 sec.
Une énorme différence.
Pour le Readcount=100, j'ai failli essayer.
Pas eu le temps de chercher la conversion tableau -> collections.
AddRange accepte une collection en entrée.
ReadCount 100 envoie des tableaux de string.
Afin de peaufiner un peu, peut-être existe t il un moyen rapide pour obtenir le nombre de ligne d'un fichier, sans utiliser gc.<br><br>Message édité par: Mephisto, à: 2/02/09 18:53
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Hors Ligne
- Modérateur
-
- Messages : 6311
- Remerciements reçus 68
De rienUn grand merci.
Mephisto écrit:
C'est surtout la reconstruction du tableau qui est pénalisante, à ce sujet consulte ce post .Les collections sont beaucoup mieux.
Mephisto écrit:
Les 2 types de collections citées acceptent un tableau.Pour le Readcount=100, j'ai failli essayer.
Pas eu le temps de chercher la conversion tableau -> collections.
AddRange accepte une collection en entrée.
ReadCount 100 envoie des tableaux de string.
La liste générique attend un objet de type IEnumerable<T> où T représente un type, ici le type String.
Et un tableau, System.Array, implémente l'interface IEnumerable.
Si tu essaies d'insérer un tableau de Int cela ne fonctionnera pas, mais avec un tableau de String pas de problème.
Mephisto écrit:
Peut avec measure-object -line.Afin de peaufiner un peu, peut-être existe t il un moyen rapide pour obtenir le nombre de ligne d'un fichier, sans utiliser gc.
Mais de toutes façons on est bien obligé de lire le fichier dans son intégralité.
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Bredin Samuel
- Auteur du sujet
- Hors Ligne
- Membre senior
-
- Messages : 52
- Remerciements reçus 0
Bonne fin de journée (Je rentre).
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Hors Ligne
- Modérateur
-
- Messages : 6311
- Remerciements reçus 68
Le d3 est un minimum de complètion avec des zéros, mais il n'y a pas de maximum :Je voulais obtenir le nombre de ligne pour définir automatiquement le 'd3' dans \"{0}_{1:d3}{2}\".
[code:1]\"_{0:d3}.\" -F 10000
#_10000.
[/code:1]
Enfin, si on parle de la même chose
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Vous êtes ici :
-
Accueil
-
forum
-
PowerShell
-
Entraide pour les débutants
- Découper fichier texte trop long (+65335 lignes)