Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 20/01/2017, à 15: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 smile

Donut

Hors ligne

#2 Le 20/01/2017, à 15: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, à 15:51

DonutMan75

Re : [SHELL] ls et basename

Bonjour Watael,
merci pour ces suggestions, je vais regarder ça smile

Bonne aprem !

Donut.

Hors ligne

#4 Le 20/01/2017, à 15: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, à 16: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. hmm
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. sad


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#6 Le 20/01/2017, à 16: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, à 17: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 roll 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 big_smile

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, à 18: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 big_smile

Bon week-end à tous !

Donut.

Hors ligne

#9 Le 21/01/2017, à 00: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 21/01/2017, à 00:52)

#10 Le 21/01/2017, à 05: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, à 05:43)

Hors ligne