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 :

Gestion des espaces dans les noms de fichiers


Sujet :

Shell et commandes GNU

  1. #1
    Membre du Club
    Homme Profil pro
    Analyse système
    Inscrit en
    Août 2020
    Messages
    160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Analyse système
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2020
    Messages : 160
    Points : 59
    Points
    59
    Par défaut Gestion des espaces dans les noms de fichiers
    Bonjour,


    Dans un fichier plat qui contient des chemins absolu de fichiers, je mets en colonne 2 la taille du fichier.

    Exemple : fichier "file_size.txt"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /home/kevin/rep1/tata 10
    /home/kevin/rep1/tutu 19
    /home/kevin/rep1/rep12/papa 26
    /home/kevin/rep1/rep11/jon 90
    /home/kevin/rep1/rep11/dady 26
    /home/kevin/rep1/rep11/brian 104
    Il se trouve dans dans la réalité certains noms de fichiers comprennent des espaces.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    /home/kevin/rep1/mon fichier  48
    Pour positionner la taille du fichier en colonne 2 j'utilise un "wc -c < nom_fichier".

    Le code que j'utilise est le suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    ...
    ...
    #on enregistre l’IFS actuel 
            OLDIFS=$IFS
    #on change l’IFS, pour être un retour à la ligne
            IFS='
            '
    for line in $(cat /home/kevin/file.txt); do echo "$line `wc -c < $line`";done > /home/kevin/file_size.txt
    #on rétablit l’IFS
            IFS=$OLDIFS
    ...
    Dans le fichier final très long file_size_"$Date" je vois des loupés, de temps en temps, et finalement je me questionne si cela ne vient pas ma gestion de l'IFS ?

    Est-elle selon vous correcte ?

  2. #2
    Expert éminent sénior Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 243
    Points : 13 458
    Points
    13 458
    Par défaut
    Bonjour

    Citation Envoyé par kevin066 Voir le message
    Est-elle selon vous correcte ?
    Non ! Tu vas fâcher les habitués du forum. Faire un "cat" dans une substitution de commande pour alimenter un "for" est sans doute la plus répandue des plus mauvaises pratiques. Ce n'est pas comme cela qu'on lit un fichier.

    Quant à l'IFS, l'affecter juste avant la commande ne le modifie que pour la commande. Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    IFS=':' read a b c <<<"toto:tata:titi"
    echo $b
    echo "|$IFS|"
    Ce qui donne :
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

  3. #3
    Membre du Club
    Homme Profil pro
    Analyse système
    Inscrit en
    Août 2020
    Messages
    160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Analyse système
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2020
    Messages : 160
    Points : 59
    Points
    59
    Par défaut
    Merci Flodelarab pour ta réponse.
    Sur ton exemple je vois mais dans mon cas avec des chemins dont le dernier champ comprend des espaces…. comment pourrais-je adapter ta méthode ? Sinon , la mienne est-elle correcte ?

  4. #4
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 278
    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 278
    Points : 12 726
    Points
    12 726
    Par défaut
    Au lieu d'utiliser une boucle for, passe par une boucle while et un read pour lire ligne à ligne ton fichier et ainsi protéger par des guillemets la valeur de ta variable.
    Cordialement.

  5. #5
    Membre du Club
    Homme Profil pro
    Analyse système
    Inscrit en
    Août 2020
    Messages
    160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Analyse système
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2020
    Messages : 160
    Points : 59
    Points
    59
    Par défaut
    Sans toucher l'IFS, en effet la solution ci-dessous est bien plus simple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while read ligne; do echo -n "$ligne " ; wc -c < "$ligne" ; done < file.txt
    Pourtant sur des fichiers de 100.000 lignes il y a des ratés, une taille non attribuée.

    Je rappelle que file.txt est un fichier du type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    chemin1/file1
    chemin2/file2
    chemin3/file3
    chemin4/file4
    Et le but de la boucle while est d'obtenir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    chemin1/file1 size1
    chemin2/file2 size2
    chemin3/file3 size3
    chemin4/file4 size4

    Quand je parle de ratés :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    chemin1/file1 size1
    chemin2/file2 size2
    chemin3/file3 chemin4/file4 size4
    chemin4/file4 size4
    Vous voyez la ligne en caractères gras ?

    Le while ne serait pas fiable? Le for non plus… et comme le disait l'un d'entre vous il n'est pas destiné à lire des fichiers.

    Qu'en pensent les experts ?

    Merci pour votre aide.

  6. #6
    Membre éprouvé Avatar de balkany
    Homme Profil pro
    Touriste
    Inscrit en
    Juillet 2017
    Messages
    346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Touriste

    Informations forums :
    Inscription : Juillet 2017
    Messages : 346
    Points : 977
    Points
    977
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while read ligne; do if [ -f "$ligne" ]; then echo -n "$ligne " ; wc -c < "$ligne" ; else echo "Il faudrait voir à renseigner votre fichier d'entrée correctement !" >&2; fi done < file.txt

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 550
    Points : 19 383
    Points
    19 383
    Par défaut
    si l'on considère l'IFS par défaut, dans ton fichier, la taille est le dernier élément de la ligne.
    en bash, soit tu passes par un tableau :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ ar=( a b c d )
    $ echo "${ar[@]: -1}"
    d
    $ echo "${ar[@]::${#ar[*]}-1}"
    a b c
    soit tu passes par le Remplacement des paramètres :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ str='a b c d'                                                                                                                                                                                                                               
    $ echo "${str##* }"                                                                                                                                                                                                                           
    d                                                                                                                                                                                                                                                                                
    $ echo "${str% *}"                                                                                                                                                                                                                            
    a b c
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  8. #8
    Expert éminent sénior Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 243
    Points : 13 458
    Points
    13 458
    Par défaut
    @balkany : la ligne contient la taille. donc le fichier n'existera jamais, ou rarement.

    Qu'en pensent les experts ?
    • Tu n'en es pas à l'étape de lire ton fichier. Tu en es à l'étape d'avoir un fichier d'entrée correct.
    • Dans le fichier de sauvegarde, je commencerais par la taille, car c'est un nombre entier sans espace. Et le reste de la ligne serait le nom de fichier.
    • J'utiliserais le ';' comme séparateur entre la taille et le nom de fichier. Ainsi, ni bash, ni awk, ne serait dérouté.
    • Enfin, j'utiliserais une commande dans ce goût-là pour créer mes futurs fichiers :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      find dossierracine/ -type f -printf "%k;%p\n" 2>/dev/null
    • La proposition de disedorgue de calculer l'empreinte est excellente car si on change une lettre du contenu de ton fichier, tu ne verras pas la différence avec ton système actuel. Même nom de fichier, même taille.
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

  9. #9
    Membre éprouvé Avatar de balkany
    Homme Profil pro
    Touriste
    Inscrit en
    Juillet 2017
    Messages
    346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Touriste

    Informations forums :
    Inscription : Juillet 2017
    Messages : 346
    Points : 977
    Points
    977
    Par défaut
    Citation Envoyé par Flodelarab Voir le message
    @balkany : la ligne contient la taille. donc le fichier n'existera jamais, ou rarement.
    Je répondais au post #5 de kevin066 : dans la situation qu'il y décrit, s'il arrive à ce résultat, c'est que son fichier file.txt est mal fichu (et ça n'est donc pas un problème de « fiabilité » de la boucle while).

  10. #10
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 278
    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 278
    Points : 12 726
    Points
    12 726
    Par défaut
    Moi, ce que je trouve bête ici, c'est d'utiliser echo -n "$ligne " ; wc -c < "$ligne" sauf pour prendre de la cpu et de l'I/O car on peut obtenir le même résultat avec stat -c "%n %s" "$ligne" mais cette fois sans se taper la lecture entière du fichier...

    Et je ne parle pas dans ce cas de l'inutilité de la boucle si on passe par un xargs pour donner les arguments à stat.
    Cordialement.

  11. #11
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 729
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 729
    Points : 15 133
    Points
    15 133
    Par défaut
    Bonjour,

    Citation Envoyé par Flodelarab Voir le message
    Quant à l'IFS, l'affecter juste avant la commande ne le modifie que pour la commande. Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    IFS=':' read a b c <<<"toto:tata:titi"
    echo $b
    echo "|$IFS|"
    Ce qui donne :
    Très intéressant (beaucoup plus visible et donc plus compréhensible avec echo "($IFS)").

    Adapté à la problématique des espaces, j'ai testé ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # IFS=':' read a b c <<<"toto tata:titi"
    # echo $a
    toto tata
    # echo $b
    titi
    # echo $c
     
    # IFS=':' read a b c <<<"tototata:titi"
    # echo $a
    tototata
    # echo $b
    titi
    # echo $c
    Conclusion : à partir du moment où on déclare le "séparateur de champs" égal à ":" alors l'espace devient un caractère comme un autre (et le 1er champ dans le cas de "toto tata" a simplement 9 caractères).
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  12. #12
    Membre du Club
    Homme Profil pro
    Analyse système
    Inscrit en
    Août 2020
    Messages
    160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Analyse système
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2020
    Messages : 160
    Points : 59
    Points
    59
    Par défaut
    Merci à vous tous pour vos propositions très intéressantes, vos conseils sont très riches d'enseignement !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Batch] Remplacer les _ par des espaces dans les noms de fichiers
    Par ricolastico dans le forum Scripts/Batch
    Réponses: 9
    Dernier message: 05/04/2018, 18h54
  2. fontion : Gestion des espaces dans les noms de dossier
    Par _stephnane_ dans le forum Scripts/Batch
    Réponses: 0
    Dernier message: 10/11/2010, 10h56
  3. Faut-il utiliser des underscores ou des espaces dans les noms des fichiers ?
    Par Invité dans le forum Général Conception Web
    Réponses: 1
    Dernier message: 07/05/2008, 19h23
  4. support des espaces dans les noms de fichiers
    Par menuge dans le forum Langage
    Réponses: 9
    Dernier message: 25/10/2006, 09h02
  5. suppression des espaces dans les noms de fichiers
    Par menuge dans le forum Général Python
    Réponses: 8
    Dernier message: 22/10/2006, 12h01

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