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

Shell et commandes GNU Discussion :

Enlever caractères blancs en début de ligne tout en conservant l'indentation


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2008
    Messages : 15
    Par défaut Enlever caractères blancs en début de ligne tout en conservant l'indentation
    Hello à tous,

    J'essaye de formater des données venant d'un fichier pour générer une documentation automatique. Pour cela, il me faut, entre les tags '\code' et '\endcode' retirer le nombre de caractères blancs qu'il y a avant le mot clé '\code', et ce sur toutes les lignes du bloc, donc en conservant les indentations éventuelles au sein de celui-ci.

    Par exemple, j'ai en entrée (les '^' représentent les espaces blancs en début de ligne):

    toto1
    ^^toto2
    ^^^^toto3
    ^^^^\code
    ^^^^Keyword =
    ^^^^{
    ^^^^^^key1 = toto4; // Comment
    ^^^^}
    ^^^^\endcode

    Je voudrais en sortie:

    toto1
    ^^toto2
    ^^^^toto3
    \code
    Keyword =
    {
    ^^key1 = toto4; // Comment
    }
    \endcode

    Merci pour votre aide !

  2. #2
    Membre émérite Avatar de jmelyn
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Septembre 2007
    Messages
    703
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Septembre 2007
    Messages : 703
    Par défaut
    Personne pour ce petit bout de code? Voici quelque chose qui semble fonctionner:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    awk '
    {
      if ($0 ~ /\\code/) {inside=1; indent=match($0, "[^ ]")}
      if (inside == 1) {$0=substr($0, indent)}
      if ($0 ~ /\\endcode/) {inside=0}
      print
    }' file_in > file_out

  3. #3
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 651
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 651
    Par défaut
    Citation Envoyé par jmelyn
    Personne pour ce petit bout de code?
    Si, si... un petit problème pour restituer les lignes qui commencent par des espaces.
    (sinon la démarche est, en gros, la même)

    Soit, on ne définit pas de nom pour la variable (comme ici), soit, il faut fixer à IFS='' (while IFS='' read var; do\#...)
    Code bash : 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
    #!/bin/bash
    
    repR=$(sed -n '/\\code/p' fichier.in)
    index=$(expr index "$repR" "\\")
    
    while read -r ; do
       if [ "$REPLY" = " *\code$" ]; then
          ch=1
       elif [ "$REPLY" = " *\endcode$" ]; then
          ch=0
       fi
       if [ ${ch:-0} = 1 ]; then
          echo "${REPLY:$index-1}"
       else
          echo "$REPLY"
       fi
    done < fichier.in
    
    versionCourte() {
    repR=$(sed -n '/\\code/p' fichier.in)
    index=$(expr index "$repR" "\\")
    while read -r 
     do
       [ "$REPLY" = " *\code$" ] && ch=1
       [ "$REPLY" = " *\endcode$" ] && ch=0
       [ ${ch:-0} = 1 ] && echo "${REPLY:$index-1}" || echo "$REPLY"
    done < fichier.in
    }
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2008
    Messages : 15
    Par défaut
    OK, merci beaucoup.

    J'ai d'abord testé avec succès le script de jmelyn. Tout semble fonctionner; Par contre, je ne vois pas quel est le petit souci évoqué par N_BaH... Tout semble bien se passer pour les lignes commençant par des espaces.

  5. #5
    Membre émérite Avatar de jmelyn
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Septembre 2007
    Messages
    703
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Septembre 2007
    Messages : 703
    Par défaut
    Bonjour N_BaH,

    D'abord, la solution que tu décris oblige à deux passages: le premier pour déterminer la tabulation à soustraire, puis le second pour le traitement; ce qui est long, notamment pour les gros fichiers. Mais le principal problème est qu'il pourrait y avoir plusieurs blocs "\code" - "\endcode" dans le fichier. Dans ce cas, il faut traiter chaque instance séparément, ce que tu ne fais pas.

    Ensuite, le code ne fonctionne pas tel quel, il y a plusieurs erreurs (j'ai pris la version courte):
    La recherche des balises "\code" et "\endcode" devrait être écrite:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [[ "$REPLY" =~ " *\\code$" ]]...
    [[ "$REPLY" =~ " *\\endcode$" ]]...
    Il reste que le flag (drapeau) pour la balise "\endcode" doit faire partie du bloc: avec décalage. Or tu fais basculer le drapeau avant d'imprimer, donc la balise "\endcode" ne sera pas décalée comme elle devrait être. La solution est de placer le traitement de cette balise après l'impression.

    Le résultat donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #!/bin/bash
     
    repR=$(sed -n '/\\code/p' fichier.in)
    index=$(expr index "$repR" "\\")
    while read -r
    do
      [[ "$REPLY" =~ " *\\code$" ]] && ch=1
      [ ${ch:-0} = 1 ] && echo "${REPLY:$index-1}" || echo "$REPLY"
      [[ "$REPLY" =~ " *\\endcode$" ]] && ch=0
    done < fichier.in > fichier.out
    Bravo pour l'aide régulière que tu apportes ici.

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    792
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 792
    Par défaut
    Variante awk:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    awk '
      /\\code/{offset=length($0)-4}
      /\\code/,/\\endcode/{print substr($0,offset)}
    ' file

  7. #7
    Membre émérite Avatar de jmelyn
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Septembre 2007
    Messages
    703
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Septembre 2007
    Messages : 703
    Par défaut
    Heu, ripat... vraiment?

    Si tu mets des patterns, ce qui ne correspond pas ne sera pas imprimé, donc ici ce qui est hors des balises disparaît. Une version corrigée donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    awk '
      /\\code/    {offset=length($0)-4}
      offset == 0 {print}
      offset != 0 {print substr($0,offset)}
      /\\endcode/ {offset=0}
    ' file_in > file_out
    Attention, le 4e pattern doit se trouver après le 3e, sinon la balise "\endcode" ne sera pas imprimée.

Discussions similaires

  1. Réponses: 3
    Dernier message: 25/09/2013, 14h53
  2. [RegEx] Ajouter un caractère à chaque début de ligne
    Par supertino7 dans le forum Langage
    Réponses: 7
    Dernier message: 02/10/2009, 20h12
  3. Insérer un caractère à chaque début de ligne
    Par xfree dans le forum Linux
    Réponses: 2
    Dernier message: 25/07/2007, 15h04
  4. [VBA-W]Insérer caractère en début de ligne.
    Par brandtance dans le forum VBA Word
    Réponses: 3
    Dernier message: 15/01/2007, 22h30
  5. Supprimer les caractères blancs en fin de ligne
    Par st20085 dans le forum Eclipse Java
    Réponses: 7
    Dernier message: 06/09/2006, 22h51

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