Pages : 1
#1 Le 20/01/2017, à 14:26
- DonutMan75
[SHELL] ls et basename
Bonjour à tous,
voilà, je cherche à récupérer la liste de tous les fichiers contenu dans un répertoire donné SANS afficher le chemin absolu mais juste le nom des fichiers...
Exemple : si mon répertoire /users/toto/test/ contient toto.txt, tata.txt et titi.txt je veux que mon script affiche
$ ./mon_script
toto.txt
tata.txt
titi.txt
basename ne fonctionnant pas sur l'entrée standard, j'ai du bidouiller un truc avec sed qui fonctionne bien mais qui n'est peut-être pas très propre...
Avez-vous une meilleure solution en tête ? (option de ls ? astuce sur basename ?)
#! /bin/sh
INPUT="/users/toto/test/"
FILE_LIST=$(ls $INPUT*txt | sed 's+.*/++g')
for f in $FILE_LIST ; do
echo $f
done
Merci d'avance
Donut
Hors ligne
#2 Le 20/01/2017, à 14:41
- Watael
Re : [SHELL] ls et basename
salut,
la méthode que tu emploies est très mauvaise pour plusieurs raisons :
- lister des éléments sans séparateurs dans une variable plate
- boucler sur une variable plate ou une sortie de commande avec for
...
#!/bin/bash
declare -a fileList
directory="/users/toto/test/"
fileList=( $directory/* )
printf '%s\n' "${fileList[@]##*/}"
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#3 Le 20/01/2017, à 14:51
- DonutMan75
Re : [SHELL] ls et basename
Bonjour Watael,
merci pour ces suggestions, je vais regarder ça
Bonne aprem !
Donut.
Hors ligne
#4 Le 20/01/2017, à 14:53
- metalux
Re : [SHELL] ls et basename
Bonjour,
ls n'est pas suffisant? Chez moi, ça me retourne bien la liste sans afficher le chemin absolu. Et pour afficher sur une colonne il faut utiliser ls -1. Je ne sais pas exactement ce que tu veux faire mais ça serait une bonne idée d'utiliser $PWD pour avoir le répertoire courant plutôt que de le coder en dur dans le script....ou encore le passer en argument du script avec $1.
@Watael
peux-tu détailler S.T.P.? Qu'est-ce une variable plate et en quoi c'est mauvais? On voit pourtant souvent ce genre de chose avec une boucle for.
Hors ligne
#5 Le 20/01/2017, à 15:17
- Watael
Re : [SHELL] ls et basename
on voit souvent de erreurs grossières concernant le shell sur internet.
quand Kevin a appris à écrire trois lignes de code, et qu'il a cru qu'il avait tout compris, il n'a évidemment pas hésité à créer une page de blog à ce sujet.
c'est Kevin, quand même ! XD
développée entre guillemets, une variable plate contient une seule donnée, contrairement à une variable tableau.
en soit ce n'est pas mauvais, mais il ne faut pas espérer itérer dessus facilement :
$ maVar="ga 'bu zo' meuh"
$ for i in $maVar; do echo "$i"; done
ga
'bu
zo'
meuh
$ for i in "$maVar"; do echo "$i"; done
ga 'bu zo' meuh
il faut se souvenir qu'il y a peu de restrictions sur les caractères pouvant être utilisés dans les noms de fichiers : les espaces, les alinéas, et autres caractères invisibles sont autorisés.
après on peut bricoler, mais ce sera toujours pataud.
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#6 Le 20/01/2017, à 15:54
- pingouinux
Re : [SHELL] ls et basename
Bonjour,
Pourquoi ne pas te mettre dans le bon répertoire en tête du script, et faire ls ?
Hors ligne
#7 Le 20/01/2017, à 16:26
- metalux
Re : [SHELL] ls et basename
une variable plate contient une seule donnée, contrairement à une variable tableau
Je n'avais pas saisi ce que c'était une variable plate, là ça prend tout son sens.
Bon, après il faut dire que je suis plus près du Kevin que de Watael ou pingouinux, disons 9 lignes de codes au lieu de trois bien que par manque de pratique je crois bien que je suis repassé au niveau Kevin! C'est aussi pour ça que:
1-Je n'ai pas de Blog sur le sujet
2-Je préfère prendre mes sources auprès de Watael ou pingouinux
pingouinux me rejoint, un bon vieux ls ferait l'affaire et se mettre dans le répertoire en début de script, indiquer le chemin en "dur", c'est vraiment pas une bonne idée, d'ailleurs je ne vois pas l'intérêt du script, autant simplement lancer la commande dans un terminal dans ce cas.
Hors ligne
#8 Le 20/01/2017, à 17:05
- DonutMan75
Re : [SHELL] ls et basename
Bonjour à tous,
en fait j'ai volontairement omis la suite du script pour ne me concentrer que sur la partie qui me posait problème, c'est vrai que présenté comme ça l'exercice peut paraît assez futile ^^
En effet faire un cd avant l'appel de ls réglerait la question, mais je me demandais s'il n'y avait pas une ruse de sioux avec basename et tout faire tenir sur une seule ligne ^^
Mettre le résultat dans une variable "plate" peut il est vrai poser problème si jamais il y a des espaces dans les répertoires ou noms de fichier. Bon dans mon cas, ce n'est pas le cas mais autant faire les choses de façon robuste dès le départ.
Pour info, mon script liste les fichiers contenu dans un répertoire donné (il ne bougera pas).
Ces fichiers sont formatés de cette façon : XXXXXXX_YYYYYY_ZZZZZZ_0103.dat avec "0103" le numéro de version du processus qui a créé le fichier.
Mon script fait une statistique sur la version du processus du genre :
$ ./mon_script
Version 0101 : 10 fichiers / 100 (10 %)
Version 0102 : 50 fichiers / 100 (50 %)
Version 0103 : 40 fichiers / 100 (40 %)
En tout cas merci pour vos retours éclairés et vos commentaires
Bon week-end à tous !
Donut.
Hors ligne
#9 Le 20/01/2017, à 23:47
- Compte anonymisé
Re : [SHELL] ls et basename
En effet faire un cd avant l'appel de ls réglerait la question, mais je me demandais s'il n'y avait pas une ruse de sioux avec basename et tout faire tenir sur une seule ligne ^^
un truc comme ça ?
find "/users/toto/test/" -name "*txt" -exec basename '{}' \;
EDIT : ou bien ça :
find "/users/toto/test/" -name "*txt" -printf "%f\n"
Dernière modification par Compte anonymisé (Le 20/01/2017, à 23:52)
#10 Le 21/01/2017, à 04:17
- MicP
Re : [SHELL] ls et basename
Bonjour
Création du répertoire :
michel@debg53sw:~$ mkdir "nom rep avec espace"
michel@debg53sw:~$
Création de 3 fichiers dans ce répertoire :
michel@debg53sw:~$ touch "nom rep avec espace"/{a..c}" fichier.nom ext ou autre"
michel@debg53sw:~$
Vérification :
michel@debg53sw:~$ ls -l "nom rep avec espace"/*
-rw-r--r-- 1 michel michel 0 janv. 21 03:47 nom rep avec espace/a fichier.nom ext ou autre
-rw-r--r-- 1 michel michel 0 janv. 21 03:47 nom rep avec espace/b fichier.nom ext ou autre
-rw-r--r-- 1 michel michel 0 janv. 21 03:47 nom rep avec espace/c fichier.nom ext ou autre
michel@debg53sw:~$
=======
Lister avec find :
michel@debg53sw:~$ find "nom rep avec espace" -type f -name *."nom ext ou autre" -printf '%f\n'
c fichier.nom ext ou autre
b fichier.nom ext ou autre
a fichier.nom ext ou autre
michel@debg53sw:~$
Lister avec find mais en utilisant des variables :
michel@debg53sw:~$ nomRep="nom rep avec espace"
michel@debg53sw:~$ nomExt="nom ext ou autre"
michel@debg53sw:~$ find "${nomRep}" -type f -name *."${nomExt}" -printf '%f\n'
c fichier.nom ext ou autre
b fichier.nom ext ou autre
a fichier.nom ext ou autre
michel@debg53sw:~$
=======
Donc, le contenu du script :
#!/bin/bash
nomRep="nom rep avec espace"
nomExt="nom ext ou autre"
find "${nomRep}" -type f -name *."${nomExt}" -printf '%f\n'
=======
Nettoyage :
michel@debg53sw:~$ rm -fr "nom rep avec espace"
michel@debg53sw:~$
Vérification :
michel@debg53sw:~$ ls -l "nom rep avec espace"
ls: impossible d'accéder à nom rep avec espace: Aucun fichier ou dossier de ce type
michel@debg53sw:~$
Dernière modification par MicP (Le 21/01/2017, à 04:43)
Hors ligne