224 votes

Comment supprimer l'extension d'un nom de fichier dans un shell script ?

Quel est le problème avec le code suivant ?

name='$filename | cut -f1 -d'.''

Tel quel, j'obtiens la chaîne littérale $filename | cut -f1 -d'.' mais si j'enlève les guillemets, je n'obtiens rien. Pendant ce temps, en tapant

"test.exe" | cut -f1 -d'.'

dans un shell me donne la sortie que je veux, test . Je sais déjà $filename s'est vu attribuer la bonne valeur. Ce que je veux faire, c'est affecter à une variable le nom du fichier sans l'extension.

1voto

MadMage Points 136

Comme l'a souligné Hawker65 dans le commentaire de la réponse de chepner, la solution la plus votée ne prend pas en compte les extensions multiples (comme filename.tar.gz), ni les points dans le reste du chemin (comme this.path/with.dots/in.path.name). Une solution possible est :

a=this.path/with.dots/in.path.name/filename.tar.gz
echo $(dirname $a)/$(basename $a | cut -d. -f1)

1voto

shaheen g Points 381

Celui-ci couvre toutes les possibilités ! (point dans le chemin ou non ; avec extension ou sans extension) :

tmp1=${filename##*/};tmp2=${tmp1:1};filename_noextension=$(echo -n ${tmp1:0:1};echo ${tmp2%.*});echo $filename_noextension

Notes :

  • Il vous donne le nom du fichier sans aucune extension. Il n'y a donc pas de chemin dans le $filename_noextension variable.
  • Vous vous retrouvez avec deux variables non désirées $tmp1 y $tmp2 . Assurez-vous que vous ne les utilisez pas dans votre script.

des exemples à tester :

filename=.bashrc; echo "filename: $filename"; tmp1=${filename##*/};tmp2=${tmp1:1};filename_noextension=$(echo -n ${tmp1:0:1};echo ${tmp2%.*}); echo "filename without extension: $filename_noextension"

filename=.bashrc.txt; echo "filename: $filename"; tmp1=${filename##*/};tmp2=${tmp1:1};filename_noextension=$(echo -n ${tmp1:0:1};echo ${tmp2%.*}); echo "filename without extension: $filename_noextension"

filename=.bashrc.txt.tar; echo "filename: $filename"; tmp1=${filename##*/};tmp2=${tmp1:1};filename_noextension=$(echo -n ${tmp1:0:1};echo ${tmp2%.*}); echo "filename without extension: $filename_noextension"

filename=~/.bashrc; echo "filename: $filename"; tmp1=${filename##*/};tmp2=${tmp1:1};filename_noextension=$(echo -n ${tmp1:0:1};echo ${tmp2%.*}); echo "filename without extension: $filename_noextension"

filename=~/.bashrc.txt.tar; echo "filename: $filename"; tmp1=${filename##*/};tmp2=${tmp1:1};filename_noextension=$(echo -n ${tmp1:0:1};echo ${tmp2%.*}); echo "filename without extension: $filename_noextension"

filename=bashrc; echo "filename: $filename"; tmp1=${filename##*/};tmp2=${tmp1:1};filename_noextension=$(echo -n ${tmp1:0:1};echo ${tmp2%.*}); echo "filename without extension: $filename_noextension"

filename=bashrc.txt; echo "filename: $filename"; tmp1=${filename##*/};tmp2=${tmp1:1};filename_noextension=$(echo -n ${tmp1:0:1};echo ${tmp2%.*}); echo "filename without extension: $filename_noextension"

filename=bashrc.txt.tar; echo "filename: $filename"; tmp1=${filename##*/};tmp2=${tmp1:1};filename_noextension=$(echo -n ${tmp1:0:1};echo ${tmp2%.*}); echo "filename without extension: $filename_noextension"

filename=~/bashrc; echo "filename: $filename"; tmp1=${filename##*/};tmp2=${tmp1:1};filename_noextension=$(echo -n ${tmp1:0:1};echo ${tmp2%.*}); echo "filename without extension: $filename_noextension"

filename=~/bashrc.txt.tar; echo "filename: $filename"; tmp1=${filename##*/};tmp2=${tmp1:1};filename_noextension=$(echo -n ${tmp1:0:1};echo ${tmp2%.*}); echo "filename without extension: $filename_noextension"

1voto

beemtee Points 111

Dans Zsh :

fullname=bridge.zip
echo ${fullname:r}

Il est simple, propre et peut être enchaîné pour supprimer plus d'une extension :

fullname=bridge.tar.gz
echo ${fullname:r:r}

Et il peut être combiné avec d'autres modificateurs .

0voto

FanDeLaU Points 79

Deux problèmes avec votre code :

  1. Vous avez utilisé un ' (cocher) au lieu d'un ` (cocher arrière) pour entourer les commandes qui génèrent la chaîne de caractères que vous voulez stocker dans la variable.
  2. Vous n'avez pas "echo" la variable "$filename" dans le pipe de la commande "cut".

Je changerais votre code en "name=`echo $filename | cut -f 1 -d '.' `", comme montré ci-dessous (encore une fois, remarquez les tics arrière entourant la définition de la variable name) :

$> filename=foo.txt
$> echo $filename
foo.txt
$> name=`echo $filename | cut -f1 -d'.'`
$> echo $name
foo
$>

-1voto

Avadh Joshi Points 9

enter image description here

En supposant que vos fichiers ont une extension .new

ls -1 | awk '{ print "mv "$1" `basename "$1" .new`"}' | sh

Puisqu'il n'affiche pas les guillemets spéciaux après avoir été posté, veuillez voir l'image.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X