Pour les fichiers dans le répertoire, uniquement le nom du fichier (pas de chemin)


99

Comment puis-je faire écho uniquement au nom de fichier d'un fichier si j'itère un répertoire avec une boucle for?

for filename in /home/user/*
do
  echo $filename
done;

tirera le chemin complet avec le nom du fichier. Je veux juste le nom du fichier.

Réponses:


166

Si vous souhaitez une bashsolution native

for file in /home/user/*; do
  echo "${file##*/}"
done

Ce qui précède utilise l' expansion des paramètres qui est native du shell et ne nécessite pas d'appel à un binaire externe tel quebasename

Cependant, pourrais-je suggérer d'utiliser simplement find

find /home/user -type f -printf "%f\n"

9
Bonne réponse. Pour ceux qui souhaitent en savoir plus sur l'expansion des paramètres: wiki.bash-hackers.org/syntax/pe#substring_removal
DougW

1
-printf: unknown primary or operator => unix.stackexchange.com/a/272493/72893
Nobita

2
Pensez à changer ${file##*/}pour "${file##*/}"prendre en charge les noms de fichiers avec des espaces, par exemple "Mon nom de fichier avec espaces.txt".
WinEunuuchs2Unix

echo "$ {file ## * /}" renvoie une chaîne vide
Alessandro C

48

Utilisez simplement basename:

echo `basename "$filename"`

Les guillemets sont nécessaires dans le cas où $ filename contient par exemple des espaces.


3
mieux utiliser l'expansion des paramètres, ne nécessite aucun appel à des binaires externes.
SiegeX

5
Btw, `` est obsolète. Mieux vaut utiliser $()comme Oli l'a fait
SiegeX

1
Désolé d'avoir commenté cette ancienne réponse, mais le nom de base ne fonctionnera pas correctement pour les fichiers avec de l'espace. Exemple: sortie PWD: /test 1, basename $(pwd)sortie: test. Testé sur OS X et Ubuntu Server (14.04). La solution native bash, comme le recommande @SiegeX, est ce qui a fonctionné pour moi.
Marko Grešak

@ MarkoGrešak Utilisez à la basename "$(pwd)"place.
YoungFrog

@YoungFrog merci pour la contribution, mais c'était il y a 9 mois. Il serait également préférable d'utiliser la variable $PWDau lieu d'exécuter la commande.
Marko Grešak

16

Utilisez basename:

echo $(basename /foo/bar/stuff)

Pourquoi utilisez-vous echo? basenameimprime déjà les résultats. echopeut même altérer le résultat si vous ne citez pas le sous-shell. Exemple: echo $(basename path/with\ \ spaces)imprime incorrectement with spaces(un seul espace).
Socowi

8

Une autre approche consiste à utiliser lslors de la lecture de la liste de fichiers dans un répertoire afin de vous donner ce que vous voulez, c'est-à-dire "juste le nom du fichier / s". Par opposition à la lecture du chemin complet du fichier, puis à l'extraction du composant "nom de fichier" dans le corps de la boucle for.

Exemple ci-dessous qui suit votre original:

for filename in $(ls /home/user/)
do
  echo $filename
done;

Si vous exécutez le script dans le même répertoire que les fichiers, il devient simplement:

for filename in $(ls)
do
  echo $filename
done;

1
lsinclut tous les fichiers dotfiles où l' *expansion ne fonctionne généralement pas. Échoue également for f in $(...) ...si un nom de fichier contient des espaces sauf si vous définissez IFS, peut échouer si un nom de fichier contient un caractère global sauf si vous définissez -f / -o noglob, et en fonction du système ou du shell echopeut échouer si un nom de fichier est un tiret + lettre ou contient une barre oblique inverse. OTOH ls -1 /path/to/dirimprime de manière fiable chaque nom de fichier sur une ligne, modulo la différence dotfiles.
dave_thompson_085

0

si vous voulez uniquement le nom de fichier:

for file in /home/user/*; do       
  f=$(echo "${file##*/}");
  filename=$(echo $f| cut  -d'.' -f 1); #file has extension, it return only filename
  echo $filename
done

pour plus d'informations sur la cutcommande, cliquez ici .

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.