Quel est le problème avec le code suivant?
name='$filename | cut -f1 -d'.''
Telle quelle, j'obtiens la chaîne littérale $filename | cut -f1 -d'.'
, mais si je supprime les guillemets, je ne reçois 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à que $filename
a reçu la bonne valeur. Ce que je veux faire, c'est assigner à une variable le nom de fichier sans l'extension.
Vous devriez utiliser la substitution commande syntax $(command)
lorsque vous souhaitez exécuter une commande dans script/command.
Donc, votre ligne serait
name=$(echo "$filename" | cut -f 1 -d '.')
Explication du code:
echo
récupère la valeur de la variable $filename
et l'envoie à la sortie standardcut
cut
utilisera le. comme séparateur (également appelé séparateur) pour couper la chaîne en segments et par -f
nous sélectionnons le segment que nous voulons avoir en sortie$()
obtiendra la sortie et renverra sa valeurname
Notez que cela donne la partie de la variable jusqu'à la première période .
:
$ 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
Vous pouvez également utiliser l'expansion des paramètres:
$ filename=foo.txt
$ echo "${filename%.*}"
foo
Si vous connaissez l'extension, vous pouvez utiliser basename
$ basename /home/jsmith/base.wiki .wiki
base
Si votre nom de fichier contient un point (autre que celui de l'extension), utilisez ceci:
echo $filename | rev | cut -f 2- -d '.' | rev
file1=/tmp/main.one.two.sh
t=$(basename "$file1") # output is main.one.two.sh
name=$(echo "$file1" | sed -e 's/\.[^.]*$//') # output is /tmp/main.one.two
name=$(echo "$t" | sed -e 's/\.[^.]*$//') # output is main.one.two
utilisez ce que vous voulez. Ici, je suppose que le dernier .
(point) suivi du texte est une extension.
Comme l'a souligné Hawker65 dans le commentaire de chepner answer, la solution la plus votée ne prend en charge ni les extensions multiples (telles que filename.tar.gz), ni les points dans le reste du chemin (tel que 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)
#!/bin/bash
filename=program.c
name=$(basename "$filename" .c)
echo "$name"
les sorties:
program
Deux problèmes avec votre code:
Je changerais votre code en "nom =` echo $ nom_fichier | cut -f 1 -d '.' `", comme indiqué ci-dessous (à nouveau, notez les graduations arrière entourant la définition de variable de nom):
$> filename=foo.txt
$> echo $filename
foo.txt
$> name=`echo $filename | cut -f1 -d'.'`
$> echo $name
foo
$>
#!/bin/bash
file=/tmp/foo.bar.gz
echo $file ${file%.*}
les sorties:
/tmp/foo.bar.gz /tmp/foo.bar
Notez que seule la dernière extension est supprimée.
Ma recommandation est d'utiliser le nom de base.
C’est par défaut dans Ubuntu, un code visuellement simple et une majorité de cas. Voici quelques sous-cas pour gérer les espaces et les sous-extensions/sous-extensions:
pathfile = "../ space fld/space -file.tar.gz"
echo $ {pathfile // + (/|. )}
En général, il se débarrasse de l’extension. mais a échoué dans notre .. chemin
echo "$ (nom de base" $ {pathfile%. *} ")"
space -file.tar # Je crois que nous avions exactement besoin de cela
Voici une remarque importante: j'ai utilisé des guillemets entre guillemets pour traiter les espaces. La citation simple ne sera pas transmise en raison de l'envoi d'un SMS au $. Bash est inhabituel et se lit "deuxième", "premier" guillemets "en raison de l'expansion.
Cependant, vous devez toujours penser à .hidden_files
hidden = "~/.bashrc" echo "$ (nom_base" $ {hidden%.} ")" # produira "~" !!!
pas le "" résultat attendu. Pour ce faire, utilisez $ HOME ou/home/chemin_utilisateur /
Parce que bash est encore "inhabituel" et ne développe pas "~" (recherche de bash BashPitfalls)
hidden2 = "$ HOME/.bashrc"; echo '$ (nom_base "$ {pathfile%. }")'