Para archivos en directorio, solo echo nombre de archivo (sin ruta)

98

¿Cómo hago para hacer eco solo del nombre de archivo de un archivo si itero un directorio con un bucle for?

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

extraerá la ruta completa con el nombre del archivo. Solo quiero el nombre del archivo.

Mechaflash
fuente

Respuestas:

166

Si quieres una bashsolución nativa

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

Lo anterior usa la expansión de parámetros que es nativa del shell y no requiere una llamada a un binario externo comobasename

Sin embargo, podría sugerir que solo use find

find /home/user -type f -printf "%f\n"
SiegeX
fuente
9
Buena respuesta. Para aquellos interesados ​​en aprender más sobre la expansión de parámetros: wiki.bash-hackers.org/syntax/pe#substring_removal
DougW
1
-printf: operador o primario desconocido => unix.stackexchange.com/a/272493/72893
Nobita
2
Considere cambiar ${file##*/}a "${file##*/}"para admitir nombres de archivo con espacios, por ejemplo, "Mi nombre de archivo con espacios.txt".
WinEunuuchs2Unix
echo "$ {file ## * /}" devuelve una cadena vacía
Alessandro C
47

Solo usa basename:

echo `basename "$filename"`

Las comillas son necesarias en caso de que $ filename contenga, por ejemplo, espacios.

Sean Bright
fuente
3
Es mejor usar la expansión de parámetros, no requiere llamadas a binarios externos.
SiegeX
5
Por cierto, `` está en desuso. Es mejor usarlo $()como lo hizo Oli
SiegeX
1
Perdón por comentar esta respuesta anterior, pero el nombre base no funcionará correctamente para archivos con espacio. Ejemplo: salida pwd: /test 1, basename $(pwd)salida: test. Probado en OS X y Ubuntu Server (14.04). La solución nativa de bash, como lo recomendó @SiegeX, es lo que funcionó para mí.
Marko Grešak
@ MarkoGrešak Utilice en su basename "$(pwd)"lugar.
YoungFrog
@YoungFrog gracias por la entrada, pero eso fue hace 9 meses. También sería mejor usar la variable en $PWDlugar de ejecutar el comando.
Marko Grešak
15

Utilizar basename:

echo $(basename /foo/bar/stuff)
Oliver Charlesworth
fuente
¿Por qué lo usas echo? basenameya imprime los resultados. echoincluso puede alterar el resultado si no cita la subcapa. Ejemplo: echo $(basename path/with\ \ spaces)imprime incorrectamente with spaces(solo un espacio).
Socowi
7

Otro enfoque es utilizarlo lsal leer la lista de archivos dentro de un directorio para darle lo que desea, es decir, "solo el nombre del archivo". A diferencia de leer la ruta completa del archivo y luego extraer el componente "nombre de archivo" en el cuerpo del bucle for.

Ejemplo a continuación que sigue a su original:

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

Si está ejecutando el script en el mismo directorio que los archivos, simplemente se convierte en:

for filename in $(ls)
do
  echo $filename
done;
Ryan
fuente
1
lsincluye cualquier archivo de puntos donde la *expansión normalmente no lo hace. También for f in $(...) ...falla si algún nombre de archivo contiene espacios en blanco a menos que establezca IFS, puede fallar si algún nombre de archivo contiene un carácter glob a menos que establezca -f / -o noglob, y dependiendo del sistema o shell echopuede fallar si algún nombre de archivo es guión + letra o contiene barra invertida. OTOH ls -1 /path/to/dirpor sí solo imprime de manera confiable cada nombre de archivo en una línea, módulo la diferencia de dotfiles.
dave_thompson_085
0

si solo desea el nombre de archivo:

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

para obtener más información sobre el cutcomando, consulte aquí .

josef
fuente