Bonjour,

A partir d’un texte du type

chaine_de_lettres1-chaine_de_chiffres1

chaine_de_lettres2-chaine_de_chiffres2

chaine_de_lettres3-chaine_de_chiffres3

J’essaie d’effectuer une inversion systématique pour obtenir ceci pour chacune :

chaine_de_chiffres-chaine_de_lettres

Un exemple concret (je ne mets que 2 lignes mais imaginons qu’il y en ait 5000) :

mon_premier-2035_08_23

toto_le_grand-2012_03_17

doit devenir

2035_08_23-mon_premier

2012_03_17-toto_le_grand

Les motifs à manipuler seraient donc du type ([a-z]*)+ et [0-9]{4}[0-9]{2}_[0-9]{2}.

J’avais lu il y a plusieurs années qu’il était possible d’enregistrer une chaîne selon son motif afin de la réutiliser mais je ne sais plus comment faire.

Généralement, je fais mes modifications de texte avec sed.

Une idée svp ?

14 jours plus tard

Bonjour,

Il faut croire que je ne suis pas au bon endroit 🙁

Je suis un peu dérouté par cette nouvelle version du forum.

En fait c’est super vague. Tu comptes faire quoi? Un programme un script? Lire à partir d’un fichier?

C’est très vague.

    xylphute

    Dans ce cas, je reprends :

    En admettant que le texte soit dans le fichier texte.txt, j’essaye de faire une modification avec la commande

    sed -i 's/chaine à modifier/nouvelle chaine/g' texte.txt

    La modification à chaque ligne consiste à récupérer un bout de la chaine initiale (dans mon exemple, la date) et le déplacer en début de chaîne. En réalité, je ne connais pas à l’avance la valeur des blocs de chiffres, donc je les détecte avec le motif suivant : [0-9]{4}[0-9]{2}_[0-9]{2}

    L’idée est qu"à chaque fois que sed trouve une chaîne qui correspond au motif, il la stocke dans une variable pour la replacer au bon endroit (ici au début de la ligne) ainsi :

    chaine à modifier = suite de caractères {sous-chaine correspondant au motif}
    nouvelle chaine = {sous-chaîne correspondant au motif}-suite de caractères

    Autrement dit en reprenant un des exemples ci-dessus : “toto_le_grand-2012_03_17” doit devenir “2012_03_17-toto_le_grand”.

    Après, pour parcourir les lignes, ça, je sais faire grace à l’option -i. Mon problème concerne uniquement ce que je mets dans mon sed.
    sed "s/je détecte ma sous-chaîne avec le motif/je réutilise ma sous-chaîne détectée précédemment pour la replacer comme dans l’exemple ci-dessus.

    Voilà, j’espère avoir été plus clair.

    fgland
    Merci pour cette doc qui montre bien comment stocker la sous-chaîne correspondant à un motif, mais je n’ai pas compris comment on la récupère dans la chaîne de sortie. J’essaie de tout faire uniquement en bash.

    je ne sais pas pour sed… est-ce une obligation de passer par sed ? est-ce une opération à faire souvent ? cette opération est trivial avec un tableur(calc).

      fgland Bonsoir fgland,
      L’idée est de modifier des noms de fichiers en masse afin de les reclasser correctement. Donc le tableur n’est pas un outil adéquat pour ce type d’opération. D’où l’intérêt de l’usage de sed.
      En fait, la commande complète va être du type :
      for FICHIERS in *; do
      __NouveauNom=$(echo $f |sed ........)
      __mv $FICHIER $NouveauNom
      done

      Actuellement, la date est à la fin des noms de fichiers et le but est de la mettre au début afin de les avoir dans leur ordre chronologique quand je fais un balayage avec ls par exemple (les dates de création/modification n’ont rien à voir pour le cas où certains y penseraient).

      Cependant, si une autre commande que sed permet de le faire plus facilement, pourquoi pas bien que j’essaye d’apprendre à le maîtriser au mieux.

      Note : Dans le code ci-dessus, j’ai mis des soulignements pour symboliser les retraits car cette nouvelle version du site supprime, hélas, les espaces et les tabulations en début de ligne.

      il aurait été bien de le préciser au départ car ton exemple est

      Dans ce cas, je reprends :
      En admettant que le texte soit dans le fichier texte.txt, j’essaye de faire une modification avec la commande

      dans ton cas, il faut faire le traitement dans ta boucle bash pour créer le nouveau nom à partir d’un split, voir par exemple : https://www.javatpoint.com/bash-split-string

      ou parmi plein de possibilités sans doute

      a_nom="mon_premier-2035_08_23"
      IFS='-' read -ra tableau <<< "$a_nom"
      n_nom=${tableau[1]}-${tableau[0]}
      echo n_nom

        fgland J’avais pensé à la solution du délimiteur, mais il y a d’autres tirets dans les noms et en quantité aléatoire, du coup, je ne peux pas me fier aux colonnes. La solution la plus fiable pour identifier le bout de chaîne à déplacer est bien une regex comme mentionnée ci-dessus.
        Je n’en ai pas encore pris le temps car je suis chargé en ce moment, mais j’ai un livre sur la LPIC-1, je vais voir si l’info que je cherche s’y trouve.
        C’est aussi un bon prétexte pour apprendre à mieux maîtriser l’usage des regex.

        j’abandonne, à chaque proposition on découvre qu’il y a une spécification qui n’a pas été donnée !

        Cependant, ma question de base est simple : comment récupérer une sous-chaine correspondant à un motif regex pour la réutiliser dans sed.

        Je cite :

        J’avais lu il y a plusieurs années qu’il était possible d’enregistrer une chaîne selon son motif afin de la réutiliser mais je ne sais plus comment faire.

        Généralement, je fais mes modifications de texte avec sed.

        Mais ,merci d’avoir essayé de m’aider.

        Pour le moment, je travaille sur mon mémoire pour ma Licence d’admin en plus de mon boulot, je n’ai pas eu le temps de poursuivre mes recherches. Je n’hésiterais pas à poster la réponse quand je l’aurais trouvée.

        Bonne nuit.