Teniendo en cuenta nombres de archivos como estos:
/the/path/foo.txt
bar.txt
Espero obtener:
foo
bar
¿Por qué no funciona?
#!/bin/bash
fullfile=$1
fname=$(basename $fullfile)
fbname=${fname%.*}
echo $fbname
¿Cuál es la forma correcta de hacerlo?
No tiene que llamar al comando externo basename
. En su lugar, puede utilizar los siguientes comandos:
$ s=/the/path/foo.txt
$ echo ${s##*/}
foo.txt
$ s=${s##*/}
$ echo ${s%.txt}
foo
$ echo ${s%.*}
foo
Tenga en cuenta que esta solución debería funcionar en todos los shells recientes (posteriores a 2004) compatibles con POSIX, (por ejemplo, bash
, dash
, ksh
, etc.).
Fuente: Lenguaje de comandos de shell 2.6.2 Expansión de parámetros
Más información sobre las manipulaciones de cadenas en bash: http://tldp.org/LDP/LG/issue18/bash.html
El comando basename tiene dos invocaciones diferentes; en una, especificas sólo la ruta, en cuyo caso te da el último componente, mientras que en la otra le das además un sufijo que eliminará. Por lo tanto, puedes simplificar tu código de ejemplo utilizando la segunda invocación de basename. Además, ten cuidado de citar correctamente las cosas:
fbname=$(basename "$1" .txt) echo "$fbname";;