IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Scripts/Batch Discussion :

Supprimer lignes d'un texte avant une expression


Sujet :

Scripts/Batch

  1. #1
    Membre du Club
    Inscrit en
    Juillet 2004
    Messages
    137
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 137
    Points : 63
    Points
    63
    Par défaut Supprimer lignes d'un texte avant une expression
    Hello,

    Je suis en train de créer un fichier log avec des infos venant de plusieurs serveurs.
    Mon fichier a à peu près cette tête :
    LOG DU 01/01/2009 ET DU 02/01/2009
    serv1 01/01/2009 infos1
    serv1 02/01/2009 infos2
    serv2 01/01/2009 infos1
    serv2 02/01/2009 infos2
    LOG DU 03/01/2009 ET DU 04/01/2009
    serv1 03/01/2009 infos1
    serv1 04/01/2009 infos2
    serv2 03/01/2009 infos1
    serv2 04/01/2009 infos2
    ETC...
    Je ne souhaite garder qu'un mois d'archivage.
    Donc, je voudrais supprimer toutes les lignes situées avant l'expression LOG DU Date à M-1.

    Trouver la date ne me pose pas de problème (je passe par les jours juliens), mais comment supprimer toutes les lignes avant ???

  2. #2
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Essaie ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    @echo off
    if "%1"=="" goto :help
    if "%2"=="" goto :help
    if "%3"=="" goto :help
    
    REM Parcours de la liste de recherche : la date.
    REM On ne cherche, en plus, que les lignes contenant le mot "LOG".
    for /f "tokens=1* delims=: " %%I in ('findstr /n "%1" %2 ^| findstr "LOG"') do (
    	REM %%I contient le numéro de ligne.
    	REM %%J contient la ligne correspondante dans le fichier de log.
    	echo Will extract from line %%I : %%J
    	echo Destination file : %3
    	REM On calcule les arguments de découpe : un délimiteur "inconnu" pour récupérer uniquement toute la ligne.
    	REM On en profite pour sauter les lignes du début jusqu'à celle trouvée au for précédent.
    	REM La ligne de début de log ne doit donc pas contenir un caractère "#" !!!
    	set ARGS="tokens=1* skip=%%I delims=#"
    	REM On recrée la 1ère ligne, car le "skip" précédent va la couper. On initialise en plus le fichier destination.
    	echo %%J > %3
    	REM On vide le reste du fichier d'origine dans le fichier destination, par concaténation.
    	for /f %ARGS% %%E in (%2) do (
    		echo %%E >> %3
    	)
    	echo   Done.
    	REM On ne tient pas compte d'éventuelles lignes "LOG" supplémentaires.
    	goto :eof
    )
    REM Fini, le fichier destination est créé, et amputé de la partie précédant la date recherchée.
    goto :eof
    
    :help
    echo Usage : %0 ^<JJ/MM/AAAA^> ^<LogFile^> ^<DestinationFile^>
    goto :eof
    Il va sans dire que si tu as mieux que la date pour trouver la ligne de découpe, ça marche aussi...
    Tu peux aussi alléger le batch si tu connais déjà le numéro de la ligne, économiser le 3ème paramètre si tu veux de toutes façons remplacer le log d'origine, etc.

  3. #3
    Membre chevronné
    Avatar de I'm_HERE
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 013
    Points : 1 991
    Points
    1 991
    Par défaut
    Salut,

    j'ai pas tester mais à première vue, le code de Mac LAK aurra des problèmes si le fichier log était un peu conséquent @voir en tout cas..

    voici une autre solution:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    set ".date.=LOG DU 01/01/2009"
    for /f "delims=:" %%a in ('findstr /nc:"%.date.%" log.txt') do (set /a cal=%%a-1)
    more +%cal% log.txt
    ** Bonne Continuation **

  4. #4
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par I'm_HERE Voir le message
    j'ai pas tester mais à première vue, le code de Mac LAK aurra des problèmes si le fichier log était un peu conséquent @voir en tout cas..
    Dans les deux cas, il y a parcours potentiel du fichier de log deux fois : la première pour trouver la ligne, la seconde pour couper ce qui est avant... A tester, bien sûr, j'ai surtout voulu être didactique et me limiter au strict nécessaire en éléments d'entrée / structures internes du fichier de log.

    Sur une machine pas spécialement performante (disques durs plutôt lents), j'obtiens 2 minutes d'exécution pour un log de 11 Mo, 300.000 lignes, découpe à partir de la ligne 150.000 : c'est pas terrible, mais ça fonctionne automatiquement.

    Par contre, sur un fichier conséquent, ton "more +n" ne fonctionnera pas : il demandera des appuis sur "Espace" de la part de l'utilisateur, y compris avec une redirection vers un fichier... Ce ne sera donc pas automatique.

    Au passage, oubli d'un "goto :eof" après la copie du log (le deuxième "for"), corrigé dans mon post précédent : ceci permet de ne prendre en compte que le PREMIER séparateur de dates, pour éviter des effets de bord pouvant être gênants.

  5. #5
    Membre chevronné
    Avatar de I'm_HERE
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 013
    Points : 1 991
    Points
    1 991
    Par défaut
    Salut Mac LAK,

    Citation Envoyé par Mac LAK Voir le message
    j'ai surtout voulu être didactique et me limiter au strict nécessaire en éléments d'entrée / structures internes du fichier de log.
    je suis d'accord avec toi sur le point didactiel de ton script.

    Citation Envoyé par Mac LAK Voir le message
    Sur une machine pas spécialement performante (disques durs plutôt lents), j'obtiens 2 minutes d'exécution pour un log de 11 Mo, 300.000 lignes, découpe à partir de la ligne 150.000 : c'est pas terrible, mais ça fonctionne automatiquement.
    c'est que j'ai tester ton script dans mon premier post et j'ai obtenu ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    LOG DU 12/10/2009 ET DU 04/01/2009 
    LOG 
    serv1 
    serv1 
    serv2 
    serv2 
    LOG 
    serv1 
    serv1 
    serv2 
    serv2 
    LOG 
    serv1 
    serv1 
    serv2 
    serv2 
    etc..
    il manque apparemment un %%F dans ta 2e boucle

    aussi, dans ta 1er boucle: 2 filtres donc 2 traitements sur une même ligne. avec un:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ('findstr /nc:"LOG DU %1" %2')
    on pourra restreindre le temps gourmand que peux prendre le filtrage


    Citation Envoyé par Mac LAK Voir le message
    Par contre, sur un fichier conséquent, ton "more +n" ne fonctionnera pas : il demandera des appuis sur "Espace" de la part de l'utilisateur, y compris avec une redirection vers un fichier... Ce ne sera donc pas automatique.
    mais d'un autre côté c'est souvent plus pratique de visualiser les logs écran par écran..

  6. #6
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par I'm_HERE Voir le message
    c'est que j'ai tester ton script dans mon premier post et j'ai obtenu ceci:
    ???? Un "%%F" serait toujours vide, vu que je découpe suivant la délimitation "#" uniquement... Je viens de retester chez moi, avec le pseudo-log de l'OP, j'obtiens bien un résultat nickel, SAUF qu'à la première exécution (console "neuve"), ça foire comme ce que tu as indiqué... Au deuxième run (puis tous les autres, quels que soient les fichiers utilisés), ça marche nickel.
    Fatigue....

    Citation Envoyé par I'm_HERE Voir le message
    aussi, dans ta 1er boucle: 2 filtres donc 2 traitements sur une même ligne. avec un:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ('findstr /nc:"LOG DU %1" %2')
    on pourra restreindre le temps gourmand que peux prendre le filtrage
    Le deuxième filtre ne s'applique qu'au résultat du premier filtre, c'est très light même sur log monstrueux... A peine perceptible, en fait.
    Le but étant surtout d'éviter de devoir connaître / matcher trop précisément la structure de la ligne de séparation de date, c'est pour ça que je ne suis limité au "LOG" exclusivement.

    Citation Envoyé par I'm_HERE Voir le message
    mais d'un autre côté c'est souvent plus pratique de visualiser les logs écran par écran..
    Là, l'OP ne veut pas consulter le log, mais conserver le dernier mois... Donc, le "sauver", ce qui implique une redirection sur un fichier.

  7. #7
    Membre chevronné
    Avatar de I'm_HERE
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 013
    Points : 1 991
    Points
    1 991
    Par défaut
    Salut,

    Bon, j'ai fait un petit test pour voir la meilleur soluion native
    (sans passer par les monstrueux Gawk,Sed,Cut..) et apparemment ta méthode est la plus adéquate

    un log de ~ 30 MO
    la cible(17/12/2009..): en ligne 213588

    Resultat
    =======

    - ta méthode: 03:28,57
    - une autre méthode (avec un petit test conditionnel): 04:17,63


    ** Bonne Continuation **

  8. #8
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par I'm_HERE Voir le message
    Bon, j'ai fait un petit test pour voir la meilleur soluion native
    (sans passer par les monstrueux Gawk,Sed,Cut..) et apparemment ta méthode est la plus adéquate
    Merci du petit benchmark, en tout cas.
    Je reste persuadé que via un outil externe, on pourrait accélérer furieusement le processus, MAIS (y'a toujours un "mais"... ) ces outils manquent sous Windows, il faudrait "importer" des outils Unix et/ou en écrire un... Si c'est pour exécuter le batch une fois par mois seulement, je pense que ça n'en vaut pas la peine.

    Par contre, j'ai trouvé le problème du premier run : problème d'expansion retardée des macros... C'est pas forcément la solution optimale, mais elle fonctionne correctement y compris au premier run sur console "vierge".

    Voilà le code corrigé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    @echo off
    if "%1"=="" goto :help
    if "%2"=="" goto :help
    if "%3"=="" goto :help
    
    REM Parcours de la liste de recherche : la date.
    REM On ne cherche, en plus, que les lignes contenant le mot "LOG".
    for /f "tokens=1* delims=: " %%I in ('findstr /n "%1" %2 ^| findstr "LOG"') do (
    	REM %%I contient le numéro de ligne.
    	REM %%J contient la ligne correspondante dans le fichier de log.
    	echo Will extract from line %%I : %%J
    	echo Destination file : %3
    	REM On calcule les arguments de découpe : un délimiteur "inconnu" pour récupérer uniquement toute la ligne.
    	REM On en profite pour sauter les lignes du début jusqu'à celle trouvée au for précédent.
    	REM La ligne de début de log ne doit donc pas contenir un caractère "#" !!!
    	setlocal enabledelayedexpansion
    	set ARGS="tokens=* skip=%%I delims= "
    	REM On recrée la 1ère ligne, car le "skip" précédent va la couper. On initialise en plus le fichier destination.
    	echo %%J > %3
    	call :flush %2 %3 !ARGS!
    	echo   Done.
    	REM On ne tient pas compte d'éventuelles lignes "LOG" supplémentaires.
    	goto :eof
    )
    REM Fini, le fichier destination est créé, et amputé de la partie précédant la date recherchée.
    goto :eof
    
    :flush
    REM On vide le reste du fichier d'origine dans le fichier destination, par concaténation.
    for /f %3 %%E in (%1) do (
    	echo %%E >> %2
    )
    goto :eof
    
    :help
    echo Usage : %0 ^<JJ/MM/AAAA^> ^<LogFile^> ^<DestinationFile^>
    goto :eof

  9. #9
    Membre éprouvé
    Avatar de maxim_um
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    895
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 895
    Points : 1 018
    Points
    1 018
    Par défaut
    Salut tout le monde,

    Citation Envoyé par I'm_HERE Voir le message
    Bon, j'ai fait un petit test pour voir la meilleur soluion native
    (sans passer par les monstrueux Gawk,Sed,Cut..)
    Citation Envoyé par Mac LAK Voir le message
    Je reste persuadé que via un outil externe, on pourrait accélérer furieusement le processus
    «Sed» serait un excellent choix.

    Mais où est passé le principal intéressé?

  10. #10
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par maxim_um Voir le message
    «Sed» serait un excellent choix.
    Pas natif Windows, et je ne suis pas certain qu'il soit plus efficace sur de très gros fichiers... Pour ma part, l'ayant utilisé quelques fois, je l'ai trouvé plutôt lent.

    Faudrait l'équivalent d'un "more +n" plutôt, mais qui ne demande aucune entrée clavier, et qui surtout permettrait derrière de vider le fichier au débit maximal une fois la limite de découpe atteinte.

    Citation Envoyé par maxim_um Voir le message
    Mais où est passé le principal intéressé?
    Sais pas, I'm_HERE et moi gardons la place au chaud en attendant...

  11. #11
    Membre éprouvé
    Avatar de maxim_um
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    895
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 895
    Points : 1 018
    Points
    1 018
    Par défaut
    Citation Envoyé par Mac LAK Voir le message
    Pas natif Windows
    Presque, il fait partie des indispensables.
    Il faut que I'm_HERE fasse une version avec «sed», sinon son bench sera incomplet, forcément.

  12. #12
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par maxim_um Voir le message
    Presque, il fait partie des indispensables.
    Pas natif quand même, donc pas présent "de base" sur toutes les machines... C'est "indispensable" pour quelqu'un qui aime et/ou a l'habitude des outils Unix, je te promets que je m'en passe très bien dans mes batchs usuels Windows !
    Surtout si, en plus, on en prend une version requérant Cygwin pour fonctionner, là, ça devient carrément laid...

  13. #13
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 6
    Points : 8
    Points
    8
    Par défaut
    Bonjour,

    je viens de lire ce post et je suis dans le même problème.
    Je désire supprimer certaines lignes de mon fichier txt, toutes les lignes contenant le mot SecId en début de ligne ( en réalité ces lignes sont des en-tetes : Secid;performanceId;...)

    Voici ce que j'ai deja fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    COPY /B RIPS_REG_ROW_*.txt RIPS_REG_ROW_TOTAL_TEMP.txt
    
    COPY /B RIPS_REG_ROW_TOTAL_TEMP.txt RIPS_REG_ROW_TOTAL.txt
    Findstr /I "SecId" < RIPS_REG_ROW_TOTAL.txt > RIPS_REG_ROW_TOTAL_TEMP.txt
    rem Del RIPS_REG_ROW_TOTAL_TEMP.txt
    Le fichier RIPS_REG_ROW_TOTAL_TEMP.txt possède bien les différentes lignes d'en-tetes mais elle ne sont pas supprimés du fichier TOTAL( fichier final)

    Pourriez vous m'expliquer pourquoi ces lignes ne sont pas supprimées ?
    Merci

  14. #14
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Déjà, si tu veux SUPPRIMER ces lignes, l'option "/V" de FindStr permet justement d'éliminer les lignes correspondant aux critères (=celles à éliminer), et ne restera donc que les lignes différentes.

Discussions similaires

  1. Réponses: 4
    Dernier message: 02/11/2009, 11h04
  2. VBS pour supprimer ligne dans ficher texte
    Par t_predator dans le forum VBScript
    Réponses: 6
    Dernier message: 11/08/2008, 15h20
  3. Réponses: 7
    Dernier message: 20/09/2007, 10h17
  4. Supprimer lignes dans fichier texte
    Par dr_octopus74 dans le forum VBScript
    Réponses: 1
    Dernier message: 20/02/2007, 17h54
  5. Formater un texte dans une expression
    Par stéphane_ais2 dans le forum Access
    Réponses: 5
    Dernier message: 18/10/2005, 13h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo