[UDF] FileDeleteLines.au3 - Supprimer lignes dans fichier

Partagez des fonctions et des UDF AutoIt.
Règles du forum
.
Répondre
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11773
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

[UDF] FileDeleteLines.au3 - Supprimer lignes dans fichier

#1

Message par Tlem »

Voici un petit UDF de trois quatres fonctions :
  • La première fonction (_FileDeleteFirstLines) permet de supprimer un certain nombre de lignes au début d'un fichier donné.
  • La deuxième fonction (_FileDeleteLastLines) permet de supprimer un certain nombre de lignes à la fin d'un fichier donné.
  • La troisième fonction (_FileDeleteLines) permet de supprimer un certain nombre de lignes à l'intérieur d'un fichier donné.
  • La quatrième fonction (_FileCountLine2) permet de connaitre le nombre de ligne d'un fichier. Certes cette fonction existe déjà (_FileCountLine), mais sur un fichier de plus de 170 Mo, un message d'erreur d'allocation mémoire apparaît (Sur mon C2D XP SP3 2go RAM).
Il est possible de modifier ces fonctions pour les rendre plus simple grâce à un tableau, mais pour un fichier de très grosse taille (plus de 170 Mo), je doute que les temps de réponse soient correct et éventuellement il risque même d'y avoir des problèmes d'allocation mémoire. :roll:
Donc pour éviter ce genre de risques, je passe par une lecture/écriture sans utiliser (ou pratiquement pas) la mémoire. ;)
Si le fichier est plus petit que 170 Mo, alors j'utilise une version optimisée de la fonction, qui est nettement plus rapide en exécution.

Il reste une quatrième fonction que je voudrais écrire et qui permettrait d'indiquer des numéros de ligne à supprimer.
Je ferais ça sans doute prochainement (si je n'oublie pas).
C'est fait ...

Voici le code de l'UDF FileDeleteLines.au3 :

Code : Tout sélectionner

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#include-once

; #FONCTION# ==============================================================================
; Nom ...........: _FileDeleteLines
; Description ...: Supprime une ou plusieurs lignes dans un fichier spécifié.
; Syntaxe .......: _FileDeleteLines($sFilePath, $iDelLines)
; Paramètres ....: $sFilePath - Chemin et nom du fichier à modifier
;                  $iDelLines - Numéro de ligne à supprimer (peut être un tableau croissant base-0 )
; Valeurs Retour : Succès - Retourne 1.
;                  Echec  - Retourne 0 et fixe l'erreur
;                           @Error - 1 = Problème de fichier
;                           @Error - 2 = Si $iDelLines n'est pas un nombre ou un tableau.
; Auteur ........: Tlem <tlem chez tuxolem point fr>
; Modifié .......:
; Remarques .....: Cette fonction n'est probablement pas optimisée pour des petits fichiers,
;                  mais elle fonctionne sur des fichiers de grosse taille.
; Apparenté .....:
; Lien ..........:
; Exemple .......:
; =========================================================================================
Func _FileDeleteLines($sFilePath, $iDelLines = 0)
    ; Test si $iDelLines est un tableau ou un nombre.
    If Not IsNumber($iDelLines) And Not IsArray($iDelLines) Then
        Return SetError(2, 0, 0)
    EndIf

    ; Ouverture du fichier source
    Local $hFilePath = FileOpen($sFilePath, 0)
    If $hFilePath = -1 Then Return SetError(1, 0, 0)

    ; Déclaration des variables utilisées dans la fonction
    Local $sTmpFile = @TempDir & "\tmpfile.txt"
    Local $ArrayIndex = 0
    Local $sLineTxt = ""
    Local $iLine = 0
    Local $i

    ; Ouverture du fichier temporaire
    Local $hFiletmp = FileOpen($sTmpFile, 2)
    If $hFiletmp = -1 Then Return SetError(1, 0, 0)

    ; Cas ou $iDelLines est un nombre
    If IsNumber($iDelLines) Then
        ; Boucle d'écriture des lignes
        While 1
            $iLine += 1
            $sLineTxt = FileReadLine($hFilePath)
            If @error = -1 Then ExitLoop
            ; Sauf la ligne $iDelLines
            If $iLine <> $iDelLines Then FileWriteLine($hFiletmp, $sLineTxt)
        WEnd
    EndIf

    ; Cas ou $iDelLines est un tableau
    If IsArray($iDelLines) Then
        ; Vérifie si $iDelLines est un tableau croissant
        If Not IsNumber($iDelLines[0]) Then SetError(2, 0, 0)
        For $i = 1 to UBound($iDelLines) -1
            If Not IsNumber($iDelLines[$i]) And $iDelLines[$i] < $iDelLines[$i - 1] Then
                SetError(2, 0, 0)
            EndIf
        Next

        ; Boucle d'écriture des lignes
        While 1
            $iLine += 1
            $sLineTxt = FileReadLine($hFilePath)
            If @error = -1 Then ExitLoop
            ; Sauf des lignes contenues dans le tableau $iDelLines
            If $iLine <> $iDelLines[$ArrayIndex] Then
                FileWriteLine($hFiletmp, $sLineTxt)
            Else
                $ArrayIndex += 1
            EndIf
        WEnd

    EndIf

    ;Fermeture des fichiers
    FileClose($hFilePath)
    FileClose($hFiletmp)

    ; Si le fichier temporaire existe (> Oko) alors on le copie à la place du fichier d'origine.
    If FileExists($sTmpFile) And FileGetSize($sTmpFile) > 0 Then
        If Not FileMove($sTmpFile, $sFilePath, 1) Then
            Return SetError(1, 0, 0)
        EndIf
    EndIf

    Return 1
EndFunc   ;==>_FileDeleteLines

; #FONCTION# ==============================================================================
; Nom ...........: _FileDeleteFirstLines
; Description ...: Supprime les premières lignes du fichier spécifié.
; Syntaxe .......: _FileDeleteFirstLines($sFilePath, $iDelLines)
; Parametres ....: $sFilePath - Chemin et nom du fichier à modifier
;                  $iDelLines - Nombre de lignes à supprimer
; Valeurs Retour : Succès - Retourne 1.
;                  Echec  - Retourne 0 est fixe l'erreur
; Auteur ........: Tlem <tlem chez tuxolem point fr>
; Modifié .......:
; Remarques .....: Cette fonction n'est probablement pas optimisée pour des petits fichiers,
;                  mais elle fonctionne sur des fichiers de grosse taille.
; Apparenté .....:
; Lien ..........:
; Exemple .......:
; =========================================================================================
Func _FileDeleteFirstLines($sFilePath, $iDelLines = 0)
    ; Ouverture du fichier source
    Local $hFilePath = FileOpen($sFilePath, 0)
    If $hFilePath = -1 Then Return SetError(1, 0, 0)

    ; Déclaration des variables utilisées dans la fonction
    Local $sTmpFile = @TempDir & "\tmpfile.txt"
    Local $sLineTxt = ""
    Local $iLine = 0

    ; Ouverture du fichier temporaire
    Local $hFiletmp = FileOpen($sTmpFile, 2)
    If $hFiletmp = -1 Then Return SetError(1, 0, 0)

    ; Boucle d'écriture des lignes
    While 1
        $iLine += 1
        $sLineTxt = FileReadLine($hFilePath)
        If @error = -1 Then ExitLoop
        If $iLine > $iDelLines Then FileWriteLine($hFiletmp, $sLineTxt)
    WEnd

    ;Fermeture des fichiers
    FileClose($hFilePath)
    FileClose($hFiletmp)

    ; Si le fichier temporaire existe (> Oko) alors on le copie à la place du fichier d'origine.
    If FileExists($sTmpFile) And FileGetSize($sTmpFile) > 0 Then
        If Not FileMove($sTmpFile, $sFilePath, 1) Then
            Return SetError(1, 0, 0)
        EndIf
    EndIf

    Return 1
EndFunc   ;==>_FileDeleteFirstLines

; #FUNCTION# ==============================================================================
; Name...........: _FileDeleteLastLines
; Description ...: Supprime les dernières lignes du fichier spécifié.
; Syntaxe .......: _FileDeleteLastLines($sFilePath, $iDelLines)
; Parametres ....: $sFilePath - Chemin et nom du fichier à modifier
;                  $iDelLines - Nombre de lignes à supprimer
; Valeurs Retour : Succès - Retourne 1.
;                  Echec  - Retourne 0 et fixe l'erreur
; Requis   ......: _FileCountLines2
; Auteur ........: Tlem <tlem chez tuxolem point fr>
; Modifié .......:
; Remarques .....: Cette fonction n'est probablement pas optimisée pour des petits fichiers,
;                  mais elle fonctionne sur des fichiers de grosse taille.
; Apparenté .....:
; Lien ..........:
; Exemple .......:
; =========================================================================================
Func _FileDeleteLastLines($sFilePath, $iDelLines = 0)
    ; Ouverture du fichier source
    Local $hFilePath = FileOpen($sFilePath, 0)
    If $hFilePath = -1 Then Return SetError(1, 0, 0)

    ; Déclaration des variables utilisées dans la fonction
    Local $sTmpFile = @TempDir & "\tmpfile.txt"
    Local $sLineTxt = ""

    ; Ouverture du fichier temporaire
    Local $hFiletmp = FileOpen($sTmpFile, 2)
    If $hFiletmp = -1 Then Return SetError(1, 0, 0)

    ; Comptage du nombre de ligne du fichier
    Local $iFileline = _FileCountLines2($sFilePath) - $iDelLines
    Local $iLine = 1

    ; Boucle d'écriture des lignes
    While $iLine <= $iFileline
        $sLineTxt = FileReadLine($hFilePath)
        If @error = -1 Then ExitLoop
        FileWriteLine($hFiletmp, $sLineTxt)
        $iLine += 1
    WEnd

    ;Fermeture des fichiers
    FileClose($hFilePath)
    FileClose($hFiletmp)

    ; Si le fichier temporaire existe (> Oko) alors on le copie à la place du fichier d'origine.
    If FileExists($sTmpFile) And FileGetSize($sTmpFile) > 0 Then
        If Not FileMove($sTmpFile, $sFilePath, 1) Then
            Return SetError(1, 0, 0)
        EndIf
    EndIf

    Return 1
EndFunc   ;==>_FileDeleteLastLines

; #FUNCTION# ==============================================================================
; Nom ...........: _FileCountLines2
; Description ...: Retourne le nombre de lignes dans le fichier spécifié.
; Syntaxe .......: _FileCountLines2($sFilePath)
; Paramètres ....: $sFilePath - Chemin et nom du fichier à lire
; Valeurs Retour : Succès - Retourne le nombre de lignes dans le fichier.
;                  Echec  - Retourne 0 et fixe l'erreur
;                  @Error  - 0 = Pas d'erreur.
;                  |1 = Le fichier ne peut être ouvert ou trouvé.
; Auteur ........: Tlem <tlem chez tuxolem point fr>
; Modifié .......:
; Remarques .....: Cette fonction est sera légèrement plus lente que la fonction d'origine, si le fichier
;                  dépasse 179 639 503 octets sinon elle sera nettement plus rapide.
;                  Ne retourne pas d'erreur d'allocation mémoire même si le fichier est > 180Mo.
; Apparenté .....:
; Lien ..........:
; Exemple .......:
; =========================================================================================
Func _FileCountLines2($sFilePath)

    ; Ouverture du fichier
    Local $hFile = FileOpen($sFilePath, 0)
    If $hFile = -1 Then Return SetError(1, 0, 0)

    ; Récupération de la taille du fichier - 1
    Local $N = FileGetSize($sFilePath) - 1
    If @error Or $N = -1 Then Return SetError(1, 0, 0)

    ; La taille de lecture d'un fichier par un FileRead ne doit pas dépasser 183 145 242 octets,
    ; sinon, il y à une erreur d'allocation mémoire.
    ; Après plusieurs test, 179 639 503 octets semble être la taille maximale dans certains cas particuliers.
    If $N + 1 <= 179639503 Then
        ; Calcul du nombre de lignes.
        Local $nbLines = StringLen(StringAddCR(FileRead($hFile, $N))) - $N + 1

        ; Fermeture du fichier
        FileClose($hFile)
        Return $nbLines
    EndIf

    Local $nbLine = 0

    ; Boucle de lecture du fichier
    While 1
        FileReadLine($hFile)
        If @error = -1 Then ExitLoop
        $nbLine += 1
    WEnd

    ; Fermeture du fichier
    FileClose($hFile)

    Return $nbLine
EndFunc   ;==>_FileCountLines2
Script d'exemple :

Code : Tout sélectionner

#include 'FileDeleteLines.au3'

; ##### _FileCountLines2 #####
; Compte le nombre de lignes du fichier.
_CreateTestFile()
MsgBox(0, 'Fichier à tester :', FileRead("Test.txt"))
MsgBox(0, 'Nombre de ligne :', _FileCountLines2("Test.txt"))


; ##### _FileDeleteLines #####
; Suppression  de toutes les lignes paires du fichier.
_CreateTestFile()
MsgBox(0, 'Avant modification _FileDeleteLines :', FileRead("Test.txt"))
Global $aLine[6] = [2, 4, 6, 8, 10]
_FileDeleteLines("Test.txt", $aLine)
MsgBox(0, 'Après modification _FileDeleteLines :', FileRead("Test.txt"))


; ##### _FileDeleteFirstLines #####
; Suppression  des 3 premières lignes du fichier.
_CreateTestFile()
MsgBox(0, 'Avant modification _FileDeleteFirstLines :', FileRead("Test.txt"))
_FileDeleteFirstLines("Test.txt", 3)
MsgBox(0, 'Après modification _FileDeleteFirstLines :', FileRead("Test.txt"))


; ##### _FileDeleteLastLines #####
; Suppression  des 3 dernières lignes du fichier.
_CreateTestFile()
MsgBox(0, 'Avant modification _FileDeleteLastLines :', FileRead("Test.txt"))
_FileDeletelastLines("Test.txt", 3)
MsgBox(0, 'Après modification _FileDeleteLastLines :', FileRead("Test.txt"))


Func _CreateTestFile()
    Local $hFile = FileOpen("Test.txt", 2)
    If $hFile = -1 Then
        MsgBox(0, "Erreur", "Impossible de créer le fichier.")
        Exit
    EndIf
    FileWrite($hFile, "Ligne 1" & @CRLF & "Ligne 2" & @CRLF & "Ligne 3" & @CRLF & "Ligne 4" & _
            @CRLF & "Ligne 5" & @CRLF & "Ligne 6" & @CRLF & "Ligne 7" & @CRLF & "Ligne 8" & _
            @CRLF & "Ligne 9" & @CRLF & "Ligne 10")
    FileClose($hFile)
EndFunc   ;==>_CreateTestFile
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
Colin117
Niveau 5
Niveau 5
Messages : 114
Enregistré le : jeu. 18 nov. 2010 17:57
Localisation : Vers là bas !
Status : Hors ligne

Re: [UDF] Supprimer des lignes dans un fichier

#2

Message par Colin117 »

Super cet UDF merci ça va beaucoup me servir prochainement.
► Afficher le texte
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11773
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: [UDF] Supprimer des lignes dans un fichier

#3

Message par Tlem »

Mise à jour du premier message.
- Ajout de la fonction _FileDeleteLines
- Ajout de commentaires sur le code.
- Mise en Français :roll: de l'UDF ...

Prochainement, ajout d'exemples.
C'est fait ... :wink:
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11773
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: [UDF] FileDeleteLines.au3 - Supprimer lignes dans fichier

#4

Message par Tlem »

Mise à jour du premier message :
- Optimisation de la fonction _FileCountLines2. Voir les commentaires de la fonction pour plus d'explications.
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
Avatar du membre
karime1
Niveau 5
Niveau 5
Messages : 106
Enregistré le : sam. 09 avr. 2011 10:05
Status : Hors ligne

Re: [UDF] FileDeleteLines.au3 - Supprimer lignes dans fichie

#5

Message par karime1 »

bonjours,
j'arrive pas a utiliser cette fonction. voici le message de la S.check
(29,43) : ERROR: FileOpen() [built-in] called with wrong number of args.
Local $hFilePath = FileOpen($sFilePath)

est ce que vous avez une idée d'ou vien le prob?
a la 29eme ligne et a deux autre y'a "fileopen" avec seulement une seule et unique option indiquer alors qu'elle requiert deux! il faut lui ajouter ,0)
donc voila le func Checké :D
Fichiers joints
FileDeleteLines.au3
func FileDeleteLines Checké, et prete a etre utilisé!
(9.73 Kio) Téléchargé 366 fois
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11773
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: [UDF] FileDeleteLines.au3 - Supprimer lignes dans fichie

#6

Message par Tlem »

karime1 a écrit :y'a "fileopen" avec seulement une seule et unique option indiquer alors qu'elle requiert deux! il faut lui ajouter ,0)
Encore une fois, manque de lecture de la documentation. :evil:
Il ne manque pas de paramètre, cette manière d'écrire était voulue car si vous aviez lu la documentation :
FileOpen
Parameters
[optional] Mode to open the file in.
Can be a combination of the following:
0 = Read mode (default)
1 = Write mode (append to end of file)
2 = Write mode (erase previous contents)
8 = Create directory structure if it doesn't exist (See Remarks).
16 = Force binary mode (See Remarks).
32 = Use Unicode UTF16 Little Endian reading and writing mode. Reading does not override existing BOM.
64 = Use Unicode UTF16 Big Endian reading and writing mode. Reading does not override existing BOM.
128 = Use Unicode UTF8 (with BOM) reading and writing mode. Reading does not override existing BOM.
256 = Use Unicode UTF8 (without BOM) reading and writing mode.
16384 = When opening for reading and no BOM is present, use full file UTF8 detection. If this is not used then only the initial part of the file is checked for UTF8.
The folder path must already exist (except using mode '8' - See Remarks).
Donc avant d'affirmer des choses, renseignez vous avant !
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
Avatar du membre
karime1
Niveau 5
Niveau 5
Messages : 106
Enregistré le : sam. 09 avr. 2011 10:05
Status : Hors ligne

Re: [UDF] FileDeleteLines.au3 - Supprimer lignes dans fichie

#7

Message par karime1 »

meme si c'est optional ça marche pas sans. je cherche pas a ce que tu me crois, je veux juste aider les gens qui ont eu/ auront le meme prob.
et aussi tu devrai remplacer
"(_DeleteFirstLines) permet de... (_DeleteLastLines) permet" par
"(_FileDeleteFirstLines) permet de... (_FileDeleteLastLines) permet"
(au debut du 1er message)
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11773
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: [UDF] FileDeleteLines.au3 - Supprimer lignes dans fichie

#8

Message par Tlem »

Je trouve étrange que cela ne fonctionne pas chez vous alors que ca fonctionne parfaitement sur 3 de mes plateformes !!!

Avez-vous la dernière version de AutoIt ?
Quel est le code qui vous donne ce messages d'erreur, car mon code d'exemple fonctionne lui aussi très bien. :shock:

Ok pour la modif sur le nom des fonctions (un reliquat des premières versions ...). :|

Edit : N'étant pas aussi fermé qu'une huitre, je concède l'ajout de l'option 0 dans le FileOpen bien qu'en réalité elle n'est pas obligatoire (cela est spécifié dans la documentation).
Mais afin d'éviter toute polémique inutile, je préfère la spécifié.
Merci de votre attention.
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
Avatar du membre
karime1
Niveau 5
Niveau 5
Messages : 106
Enregistré le : sam. 09 avr. 2011 10:05
Status : Hors ligne

Re: [UDF] FileDeleteLines.au3 - Supprimer lignes dans fichie

#9

Message par karime1 »

ouais c'était ça le prob. bon j'ai fait maintenant la mise a jour mais un autre prob est apparu: j'ai essayé de transformer la filedeletefirstlines a une qui cherche elle ou s'arrêter de supprimer.explication:
robot!
je veux que tu efface toute les ligne jusqu'à ce que tu arrive a la ligne ou est écrit "Chapitre 2"
dans un fichier txt ou il y'a "Chapitre1"& @CRLF &" bla bla bla"& @CRLF &"Chapitre 2"& @CRLF &" bla bla bla Chap ..."
alors voila

Code : Tout sélectionner

#Include <FileDeleteLines.au3>
Global $File="D:\Lol.txt"
$TotalLineNumber=_FileCountLines2($File)
$FileData = FileOpen($File)
For $LineNumber=1 To $TotalLineNumber Step 1
    $LineData = FileReadLine($FileData,$LineNumber)
    FileClose($File)
    If @error = -1 Then Exit 20
    If $LineData="Chapitre 2" Then
        _FileDeleteFirstLines($File,$LineNumber-1)
        ExitLoop
    EndIf
Next
mais tout ce qu'il fait c'est effacer le fichier!
(et désoler pour la réponse en retard j'essayai de résoudre moi même le prob)
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11773
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: [UDF] FileDeleteLines.au3 - Supprimer lignes dans fichie

#10

Message par Tlem »

Cette section n'est pas la bonne pour les demandes d'aide.
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
Répondre