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 :

Bash - Commande SED suppression caractère


Sujet :

Shell et commandes GNU

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 62
    Points : 35
    Points
    35
    Par défaut Bash - Commande SED suppression caractère
    Bonsoir,

    Je souhaite renommer des fichiers présents dans un répertoire qui ont cette tête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TOTO_A001_28092017_4276193.fic_2017100518291507220973313
    vers ce formalisme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TOTO_A001_2017100518291507220973313
    Donc supprimer toute la chaine de caractère entre A001_ et 201710

    Je pense qu'il faut utiliser la commande sed mais je n'arrive pas à la dompter.

    Merci pour votre aide

  2. #2
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    salut,

    puisqu'il s'agit de renommer, autant utiliser rename (il faut installer le package il me semble) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ rename -v 's/A001_.+?201710/A001_201710/' TOTO_A001_28092017_4276193.fic_2017100518291507220973313
    TOTO_A001_28092017_4276193.fic_2017100518291507220973313 renamed as TOTO_A001_2017100518291507220973313
    edit:
    si pas possible d'installer le pkg, la version longue existe néanmoins :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for src in *; do dest=$(sed -r 's/A001_.+?201710/A001_201710/' <<< "$src"); mv "$src" "$dest"; done

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2010
    Messages
    345
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 345
    Points : 539
    Points
    539
    Par défaut
    Bonjour,
    Comme il n'y a pas trop de détails, juste le sed a coupler avec un find peut être.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -E 's/([^_]*_)([^_]*).*(_.*$)/\1\2\3/'
    Cordialement.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2010
    Messages
    345
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 345
    Points : 539
    Points
    539
    Par défaut
    encore mieux je pense.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -E 's/([^_]*_)//3;s/([^_]*_)//3'
    Cordialement.

  5. #5
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par dahu29 Voir le message
    Je souhaite renommer des fichiers présents dans un répertoire qui ont cette tête :
    TOTO_A001_28092017_4276193.fic_2017100518291507220973313
    vers ce formalisme
    TOTO_A001_2017100518291507220973313

    Donc supprimer toute la chaine de caractère entre A001_ et 201710
    Citation Envoyé par BufferBob Voir le message
    la version longue existe néanmoins :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for src in *; do dest=$(sed -r 's/A001_.+?201710/A001_201710/' <<< "$src"); mv "$src" "$dest"; done
    Attention!

    Cette commande va traiter tous les fichiers, même ceux qui ne sont pas concernés, ce qui ne va pas faire joli (mv "$src" "$src")!

    Je préfèrerais ne traiter que les fichiers concernés (s'il y en a d'autres dans le même répertoire):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for src in *A001_*201710*; do dest=$(sed -r 's/A001_.+?201710/A001_201710/' <<< "$src"); mv "$src" "$dest"; done
    De plus, je te souhaite fortement de ne pas avoir de fichier contenant plusieurs occurrences de 201710, comme par exemple TOTO_A001_28092017_4276193.fic_2017100518291507220171013 qui risque d'être salement raccourci!

    On peut limiter la casse en mettant le "_" devant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for src in *A001_*201710*; do dest=$(sed -e 's/A001_.*_201710/A001_201710/' <<< "$src"); mv "$src" "$dest"; done
    Au fait, qui a eu cette idée folle un jour d'inventer un tel nommage???

  6. #6
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    Citation Envoyé par jack-ft Voir le message
    De plus, je te souhaite fortement de ne pas avoir de fichier contenant plusieurs occurrences de 201710, comme par exemple TOTO_A001_28092017_4276193.fic_2017100518291507220171013 qui risque d'être salement raccourci!
    arf exact, sed ne prend pas en compte .+? comme opérateur non-greedy
    une raison de plus d'utiliser rename, avis perso...

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 62
    Points : 35
    Points
    35
    Par défaut
    Bonjour,

    Merci à vous

    J'ai testé la commande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for src in *A001_*201710*; do dest=$(sed -r 's/A001_.+?201710/A001_201710/' <<< "$src"); mv "$src" "$dest"; done
    Elle déclenchait des erreurs de ce type :
    mv: â#TOTO_A001.fic_2017100518291507220973273â and â#TOTO_A001.fic_2017100518291507220973273â are the same file

    J'ai donc exécuté cette commande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -E 's/([^_]*_)//3;s/([^_]*_)//3'
    Elle a bien fonctionné mais elle ne rend pas la main.
    Je me demande si elle ne parse pas tous les fichiers présents dans le répertoire (1,5go de fichiers txt)

  8. #8
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 274
    Points : 12 709
    Points
    12 709
    Par défaut
    Bonjour,

    Non, tel quel, le sed attend que tu entres des choses au clavier (entrée standard).

    Et d'ailleurs dans le cas de la boucle for, je ne vois pas trop l’intérêt du sed:
    Si on considère que tu souhaites renommer un fichier qui ressemble à <mot1>_A001_<mot2>_<mot3>_<mot4> et qu'au final, ça doit être <mot1>_A001_<mot4>, on peut le faire en:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for i in *_A001_*_*_*; do IFS="_" read mot1 A001 mot2 mot3 mot4 <<<$i; echo mv "$i" "${mot1}_${A001}_${mot4}";done
    Cordialement.

  9. #9
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par dahu29 Voir le message
    J'ai testé la commande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for src in *A001_*201710*; do dest=$(sed -r 's/A001_.+?201710/A001_201710/' <<< "$src"); mv "$src" "$dest"; done
    Elle déclenchait des erreurs de ce type :
    mv: â#TOTO_A001.fic_2017100518291507220973273â and â#TOTO_A001.fic_2017100518291507220973273â are the same file
    C'est exactement ce que j'avais prévu!

    Il suffisait de lire ce que j'avais écrit:

    Citation Envoyé par jack-ft Voir le message
    Attention!

    Cette commande va traiter tous les fichiers, même ceux qui ne sont pas concernés, ce qui ne va pas faire joli (mv "$src" "$src")!
    Et j'ai même proposé une amélioration pour éviter cette erreur:

    Citation Envoyé par jack-ft Voir le message
    Je préfèrerais ne traiter que les fichiers concernés (s'il y en a d'autres dans le même répertoire):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for src in *A001_*201710*; do dest=$(sed -e 's/A001_.*_201710/A001_201710/' <<< "$src"); mv "$src" "$dest"; done
    Au fait, qui a eu cette idée folle un jour d'inventer un tel nommage???
    Citation Envoyé par dahu29 Voir le message
    J'ai donc exécuté cette commande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -E 's/([^_]*_)//3;s/([^_]*_)//3'
    Elle a bien fonctionné mais elle ne rend pas la main.
    Non non! Cette commande ne peut pas marcher toute seule!
    C'est la commande précédente qui a bien fait le boulot, mais avec des messages d'erreur sans gravité.

    ctac_ a indiqué qu'il ne donnait qu'une partie de la commande (à coupler avec un "find").

Discussions similaires

  1. Script Bash commande sed non prise en compte
    Par wesswessa dans le forum Shell et commandes GNU
    Réponses: 2
    Dernier message: 16/10/2013, 14h21
  2. Commande SED pour suppression de blancs ou tabulations
    Par patgabjoe dans le forum Programmation système
    Réponses: 1
    Dernier message: 24/08/2011, 12h19
  3. [commande sed] substitution de caractères
    Par matrix788 dans le forum Linux
    Réponses: 6
    Dernier message: 25/02/2011, 20h33
  4. commande sed (bash)
    Par bossy451 dans le forum Linux
    Réponses: 1
    Dernier message: 28/03/2010, 18h41
  5. Réponses: 3
    Dernier message: 24/04/2009, 09h12

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