Forum Programmation.shell Est-ce un fichier ? Un répertoire ? Et histoire de pipelines.

Posté par  .
Étiquettes : aucune
0
5
sept.
2005
Bonjour à tous.

Je suis en train d'écrire un programme en shell bash permettant le déplacement automatique de fichiers. Le programme se trouvant ci-dessous fonctionne.
De quoi s'agit-il? Les employés d'une entreprise d'audit créés, chaque fois qu'une entreprise est auditée, un fichier contenant leur rapport sous /home/[le rep de l'auditeur] (es : Jacques dépose ses rapports dans /home/Jacques). Le rapport est de la forme [nom de l'entreprise].extension (ex : Renault.doc).
Le programme déplace les rapports des auditeurs et les place sous /Rapports/[nom de l'entreprise] (ex : le rapport renault.doc de Jacques sera placé sous /Rapports/Renault). Eventuellement, si l'entreprise est auditée pour la première fois (et qu'il n'y a donc pas encore de répertoire à son nom sous /Rapports), le programme créé un répertoire au nom de l'entreprise. Le premier rapport déposé prendra alors le nom, par exemple, Sony.001.doc.
Si l'entreprise a été auditée plusieurs fois, le programme renomme le rapports en le déplaçant. Ainsi, le 2nd rapport sur Renault s'appellera Renault.002.doc, le 3ième, Renault.003.doc, etc...
N'hésitez pas à me demandez des précisions si je n'ai pas été assez clair.

1) Si le programme rencontre un fichier dans le répertoire réservé aux auditeurs /home, il se plante. Même chose si c'est un répertoire
dans le répertoire d'un auditeur, où il ne devrait y avoir que des fichiers. Comment s'écrivent les tests "si tel objet est un répertoire" et "si tel objet est un fichier" ?

2) A partir de la ligne "d=$(ls -1 | tail -1)" jusqu'à la ligne "d=$(echo $d | sed 's/^0*//')", j'ai écris une série de commande que je voudrais en une seule ligne, en faisant un truc du genre :
d=$(ls -1 | tail -1 | ${d%*.*} | ${d##*.} | sed 's/^0*//')
mais qui fonctionne, bien sûr!
Y a t'il un moyen de faire ça?



#! /bin/bash

# Le programme suivant prend en compte un nombre illimité d'auditeurs et jusqu'à 999 rapports.
# Les rapports sont traités quelque soit leur extension.
# Le nom des rapports peut contenir n'importe quel signe y compris les espaces.
# Le nom des rapports classés est de la forme 'société.001.ext'.
# Le fait d'ajouter un point entre le nom de la société et le numéro permet de prendre
# en compte la présence éventuelle de chiffres dans le nom de la société.

# Variables :
# a = répertoires des auditeurs sous /home
# b = rapports non classés
# c = nom de la société auditée
# d = numéro du dernier rapport classé
# e = extension du rapport

cd /home

for a in * ; do

if [ "$a" = \* ] ; then
break
fi

cd "/home/$a"

for b in * ; do

if [ "$b" = \* ] ; then
continue
fi

# on extrait du nom du rapport le nom de la société
# c'est à dire tout ce qui est avant le dernier point
c=${b%*.*}
# on récupère l'extension du rapport à classer
# c'est à dire tout ce qui est après le dernier point
e=.${b##*.}
cd /Rapports
# un répertoire au nom de la société existe-t-il déjà?
if [ -d "$c" ] ; then
cd "$c"
# on extrait de la liste le dernier fichier ajouté
# (celui dont le nombre est le plus grand)
d=$(ls -1 | tail -1)
# on retire au fichier son extension
d=${d%*.*}
# on extrait son numéro
d=${d##*.}
# on supprime les zéros non significatifs
d=$(echo $d | sed 's/^0*//')
# on incrémente ce numéro de 1
d=$(($d + 1))
# on lui accolle 2 '0'
d=00$d
# on extrait les 3 premiers chiffres (à partir de la droite)
# \([0-9][0-9][0-9]\) et \1 : motif conservant les 3 chiffres de droite
d=$(echo $d | sed 's/^0*\([0-9][0-9][0-9]\)/\1/g')
# on déplace enfin le rapport du répertoire de l'auditeur
# dans le répertoire de la société en le renommant
mv "/home/$a/$b" "/Rapports/$c/$c"."$d$e"

else
# on crée un répertoire au nom de la société
mkdir "/Rapports/$c"
# on y déplace alors le rapport en lui attribuant le numéro '001'
mv "/home/$a/$b" "/Rapports/$c/$c".001"$e"

fi

done

done


Merci bien pour votre attention!
  • # Essaie ca

    Posté par  (site web personnel) . Évalué à 2.

    1) la commande file retourne si l'entrée est un fichier ou un répertoire
    2) remplace le $() par des backquotes: `echo $d | sed 's/^0*\([0-9][0-9][0-9]\)/\1/g'`
    • [^] # Re: Essaie ca

      Posté par  (site web personnel) . Évalué à 2.

      pourquoi remplacer $() par des backquotes ?
      $() est plus souple et permet d'imbriquer plusieurs $() contrairement aux backquotes
      • [^] # Re: Essaie ca

        Posté par  . Évalué à 0.

        on peut imriquer des backquotes en les protegeant, c'est un peu plus penible, mais ce qu'on perd en souplesse, on le gagne en protabilite (enfin, c'est ce que je pense, je n'ai pas essaye $() sur un sh posix non gnu)
  • # Re : Est-ce un fichier ? Un répertoire ? Et histoire de pipelines.

    Posté par  . Évalué à 0.

    mkdir -p rep cree le repertoire 'rep' s'il n'existe pas, ne fait rien sinon, a mon avis, c'est plus simple et plus joli que de faire un test

    basename permet peut etre de faire ce que tu fais qd tu supprime l'extension & co (en fait peut etre pas, si l'extension n'est pas fixe :/ )

    et pour recuperer le nombre de fichier deja cree pour une societe, un ls -l | wc -l me semble plus simple que de faire les manips sur le dernier fichier, ce qui donne :
    d=`EXPR \`LS -l | WC -l\` \+ 1`

    ah oui, essaye d'utiliser une variable pour les appels a des binaires, ca permet d'eviter un alias du type ls='ls -a' qui donne un resultat foireux avec ma methode (en l'occurence, la j'aurais EXPR=/usr/bin/expr LS=...)
    • [^] # Re: Re : Est-ce un fichier ? Un répertoire ? Et histoire de pipelines.

      Posté par  . Évalué à 1.

      j'ai oublie de l'indiquer, mais ce que je viens de dire est "sh approved" ce qui est encore mieux que de supposer que bash est installe :)

      et si l'utilisateur fais un lien /bin/sh -> /bin/csh, alors c'est un peu la merde, mais on peut toujours tester ca au debut :/

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.