Per i file nella directory, solo echo filename (nessun percorso)


98

Come posso fare per riprodurre solo il nome di un file se itero una directory con un ciclo for?

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

estrarrà il percorso completo con il nome del file. Voglio solo il nome del file.

Risposte:


166

Se vuoi una bashsoluzione nativa

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

Quanto sopra usa l' espansione dei parametri che è nativa della shell e non richiede una chiamata a un binario esterno comebasename

Tuttavia, potrei suggerire solo di usare find

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

9
Buona risposta. Per coloro interessati a saperne di più sull'espansione dei parametri: wiki.bash-hackers.org/syntax/pe#substring_removal
DougW

1
-printf: operatore o primario sconosciuto => unix.stackexchange.com/a/272493/72893
Nobita

2
Considera l' idea di passare ${file##*/}a "${file##*/}"per supportare i nomi di file con spazi, ad esempio "Il mio nome di file con spazi.txt".
WinEunuuchs2Unix

echo "$ {file ## * /}" restituisce una stringa vuota
Alessandro C

47

Usa solo basename:

echo `basename "$filename"`

Le virgolette sono necessarie nel caso in cui $ nomefile contenga, ad esempio, spazi.


3
meglio usare l'espansione dei parametri, non richiede chiamate a binari esterni.
SiegeX

5
A proposito, `` è deprecato. Meglio usare $()come ha fatto Oli
SiegeX

1
Ci scusiamo per aver commentato questa vecchia risposta, ma basename non funzionerà correttamente per i file con spazio. Esempio: uscita pwd: /test 1, basename $(pwd)uscita: test. Testato su OS X e Ubuntu Server (14.04). La soluzione bash nativa, come consigliato da @SiegeX, è ciò che ha funzionato per me.
Marko Grešak

@ MarkoGrešak Usa basename "$(pwd)"invece.
YoungFrog

@YoungFrog grazie per l'input, ma è stato 9 mesi fa. Inoltre sarebbe meglio usare la variabile $PWDinvece di eseguire il comando.
Marko Grešak

15

Usa basename:

echo $(basename /foo/bar/stuff)

Perché lo usi echo? basenamestampa già i risultati. echopotrebbe persino alterare il risultato se non si cita la subshell. Esempio: echo $(basename path/with\ \ spaces)stampa in modo errato with spaces(solo uno spazio).
Socowi

7

Un altro approccio è quello di usare lsquando si legge l'elenco dei file all'interno di una directory in modo da darvi ciò che volete, cioè "solo il nome / i file". Invece di leggere il percorso completo del file e quindi estrarre il componente "nome file" nel corpo del ciclo for.

Esempio di seguito che segue il tuo originale:

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

Se stai eseguendo lo script nella stessa directory dei file, diventa semplicemente:

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

1
lsinclude qualsiasi dotfile in cui l' *espansione di solito non lo fa. Inoltre for f in $(...) ...fallisce se un nome file contiene spazi vuoti a meno che non si imposti IFS, potrebbe non riuscire se un nome file contiene un carattere glob a meno che non si imposti -f / -o noglob e, a seconda del sistema o della shell, echopotrebbe non riuscire se un nome file è trattino + lettera o contiene barra rovesciata. OTOH ls -1 /path/to/dirda solo stampa in modo affidabile ogni nome di file su una riga, modulo la differenza dei dotfile.
dave_thompson_085

0

se vuoi solo il nome del file:

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

per ulteriori informazioni sul cutcomando vedere qui .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.