¿Cómo puedo eliminar la extensión de un nombre de archivo en un script de Shell?
¿Qué hay de malo con el siguiente código?
name='$filename | cut -f1 -d'.''
Tal como está, obtengo la cadena literal $filename | cut -f1 -d'.'
, pero si elimino las comillas no obtengo nada. Mientras tanto, escribiendo
"test.exe" | cut -f1 -d'.'
en un shell me da el resultado que quiero test
. Ya sé que $filename
se le ha asignado el valor correcto. Lo que quiero hacer es asignar a una variable el nombre del archivo sin la extensión.
También puede utilizar la expansión de parámetros:
$ filename=foo.txt
$ echo "${filename%.*}"
foo
Si tiene una ruta de archivo y no solo un nombre de archivo , querrá usarla basename
primero para obtener solo el nombre del archivo, incluida la extensión. De lo contrario, si hay un punto sólo en el trazado (por ejemplo, path.to/myfile
o ./myfile
), se recortará dentro del trazado; incluso si no hay un punto en la ruta, obtendrá (por ejemplo, path/to/myfile
si la ruta es path/to/myfile.txt
):
$ filepath=path.to/foo.txt
$ echo "${filepath%.*}"
path.to/foo
$ filename=$(basename $filepath)
$ echo $filename
foo.txt
$ echo "${filename%.*}"
foo
Sólo tenga en cuenta que si el nombre del archivo solo comienza con un punto (por ejemplo .bashrc
), se eliminará todo el nombre del archivo.
Si conoce la extensión, puede usar el nombre base
$ basename /home/jsmith/base.wiki .wiki
base
Debería utilizar la sintaxis de sustitución de comandos$(command)
cuando desee ejecutar un comando en un script/comando.
Entonces tu línea sería
name=$(echo "$filename" | cut -f 1 -d '.')
Explicación del código:
echo
obtener el valor de la variable$filename
y enviarlo a la salida estándar- Luego tomamos la salida y la canalizamos al
cut
comando cut
Utilizará el . como delimitador (también conocido como separador) para cortar la cadena en segmentos y seleccionamos-f
qué segmento queremos tener en la salida- Entonces la
$()
sustitución del comando obtendrá el resultado y devolverá su valor. - El valor devuelto se asignará a la variable denominada
name
Tenga en cuenta que esto da la porción de la variable hasta el primer período .
:
$ filename=hello.world
$ echo "$filename" | cut -f 1 -d '.'
hello
$ filename=hello.hello.hello
$ echo "$filename" | cut -f 1 -d '.'
hello
$ filename=hello
$ echo "$filename" | cut -f 1 -d '.'
hello
Si su nombre de archivo contiene un punto (distinto al de la extensión), utilice esto:
echo $filename | rev | cut -f 2- -d '.' | rev
Utilizando únicamente el integrado de POSIX:
#!/usr/bin/env sh
path=this.path/with.dots/in.path.name/filename.tar.gz
# Get the basedir without external command
# by stripping out shortest trailing match of / followed by anything
dirname=${path%/*}
# Get the basename without external command
# by stripping out longest leading match of anything followed by /
basename=${path##*/}
# Strip uptmost trailing extension only
# by stripping out shortest trailing match of dot followed by anything
oneextless=${basename%.*}; echo "$oneextless"
# Strip all extensions
# by stripping out longest trailing match of dot followed by anything
noext=${basename%%.*}; echo "$noext"
# Printout demo
printf %s\\n "$path" "$dirname" "$basename" "$oneextless" "$noext"
Demostración impresa:
this.path/with.dots/in.path.name/filename.tar.gz
this.path/with.dots/in.path.name
filename.tar.gz
filename.tar
filename