Question Découper fichier texte trop long (+65335 lignes)

Plus d'informations
il y a 17 ans 1 mois #3879 par Bredin Samuel
Bonjour messieurs dames,

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.

Plus d'informations
il y a 17 ans 1 mois #3881 par Laurent Dardenne
Réponse de Laurent Dardenne sur le sujet Re:Découper fichier texte
Salut,
utilise une collection et pas un tableau, le recyclage de la mémoire sera meilleur :
[code:1]
$Collections=New-Object \&quot;System.Collections.Generic.List``1[System.String]\&quot;
# Ou $Collections=New-object System.Collections.Specialized.StringCollection[/code:1]
Utilise une chaîne de formatage au lieu du test
[code:1]
#Leading zero
\&quot;_{0:d3}\&quot; -f 10
$FichierFinal = \&quot;{0}_{1:d3}{2}\&quot; -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 \&quot;System.Collections.Generic.List``1[System.String]\&quot;
} -Process {
$i++
[void]$Collections.Add($_)

if ($i % $NbLigne -eq 0) {
$FichierFinal = \&quot;{0}_{1:d3}{2}\&quot; -F $NomFichier,$j,$objFile.Extension
$Collections.GetEnumerator() | Out-File -filePath $FichierFinal
$Collections.Clear()
$j++
}
} -End {
$FichierFinal = \&quot;{0}_{1:d3}{2}\&quot; -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 :P

ps :
On peut changer l'extension ainsi
[code:1][System.IO.Path]::ChangeExtension($F.FullName,\&quot;\&quot;«»)[/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.

Plus d'informations
il y a 17 ans 1 mois #3885 par Bredin Samuel
Réponse de Bredin Samuel sur le sujet Re:Découper fichier texte
Bonjour Laurent,

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 -&gt; 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.

Plus d'informations
il y a 17 ans 1 mois #3886 par Laurent Dardenne
Réponse de Laurent Dardenne sur le sujet Re:Découper fichier texte
Mephisto écrit:

Un grand merci.

De rien :)
Mephisto écrit:

Les collections sont beaucoup mieux.

C'est surtout la reconstruction du tableau qui est pénalisante, à ce sujet consulte ce post .
Mephisto écrit:

Pour le Readcount=100, j'ai failli essayer.
Pas eu le temps de chercher la conversion tableau -&gt; collections.

AddRange accepte une collection en entrée.
ReadCount 100 envoie des tableaux de string.

Les 2 types de collections citées acceptent un tableau.
La liste générique attend un objet de type IEnumerable&lt;T&gt; 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:

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.

Peut avec measure-object -line.
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.

Plus d'informations
il y a 17 ans 1 mois #3887 par Bredin Samuel
Réponse de Bredin Samuel sur le sujet Re:Découper fichier texte
Je voulais obtenir le nombre de ligne pour définir automatiquement le 'd3' dans \&quot;{0}_{1:d3}{2}\&quot;.

Bonne fin de journée (Je rentre).

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 17 ans 1 mois #3889 par Laurent Dardenne
Réponse de Laurent Dardenne sur le sujet Re:Découper fichier texte
Mephisto écrit:

Je voulais obtenir le nombre de ligne pour définir automatiquement le 'd3' dans \&quot;{0}_{1:d3}{2}\&quot;.

Le d3 est un minimum de complètion avec des zéros, mais il n'y a pas de maximum :
[code:1]\&quot;_{0:d3}.\&quot; -F 10000
#_10000.
[/code:1]
Enfin, si on parle de la même chose :silly:

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.101 secondes
Propulsé par Kunena