2461 votes

Extrait de nom de fichier et extension en bash

Je veux obtenir le nom de fichier (sans extension) et l'extension séparément.

La meilleure solution que j'ai trouvé pour l'instant est:

NAME=`echo "$FILE" | cut -d'.' -f1`
EXTENSION=`echo "$FILE" | cut -d'.' -f2`

C'est faux, car il ne fonctionne pas si le nom de fichier contient plusieurs "." des personnages. Si disons que j'ai a.b.js il envisagera un et b.js, au lieu d' un.b et js.

Il peut être facilement fait en Python avec

file, ext = os.path.splitext(path)

mais je préfère ne pas tirer un interpréteur Python juste pour ça, si possible.

Toutes les meilleures idées?

3975voto

Petesh Points 29374

Tout d'abord, obtenir le fichier sans le chemin d'accès:

filename=$(basename "$fullfile")
extension="${filename##*.}"
filename="${filename%.*}"

Alternativement, vous pouvez vous concentrer sur le dernier " / "du chemin d'accès au lieu de le". " qui devrait fonctionner même si vous avez imprévisible des extensions de fichier:

filename="${fullfile##*/}"

896voto

Juliano Points 13802
~% FILE="example.tar.gz"
~% echo "${FILE%%.*}"
example
~% echo "${FILE%.*}"
example.tar
~% echo "${FILE#*.}"
tar.gz
~% echo "${FILE##*.}"
gz

Pour plus de détails, voir shell paramètre d'expansion dans le manuel de bash.

537voto

Tomi Po Points 529

Habituellement, vous connaissez déjà l'extension, de sorte que vous pouvez les utiliser:

basename filename .extension

par exemple:

basename /path/to/dir/filename.txt .txt

et nous obtenons

filename

84voto

Doctor J Points 1023

Cela ne semble pas fonctionner si le fichier n'a pas d'extension, ou pas de nom de fichier. Voici ce que j'utilise; il utilise uniquement les objets internes et les poignées de plus (mais pas tous) les noms de fichiers pathologiques.

#!/bin/bash
for fullpath in "$@"
do
    filename="${fullpath##*/}"                      # Strip longest match of */ from start
    dir="${fullpath:0:${#fullpath} - ${#filename}}" # Substring from 0 thru pos of filename
    base="${filename%.[^.]*}"                       # Strip shortest match of . plus at least one non-dot char from end
    ext="${filename:${#base} + 1}"                  # Substring from len of base thru end
    if [[ -z "$base" && -n "$ext" ]]; then          # If we have an extension and no base, it's really the base
        base=".$ext"
        ext=""
    fi

    echo -e "$fullpath:\n\tdir  = \"$dir\"\n\tbase = \"$base\"\n\text  = \"$ext\""
done

Et voici quelques cas de tests:

$ basename-and-extension.sh / /home/moi/ /home/moi/fichier /home/moi/fichier.tar /home/me/file.tar.gz /home/moi/.caché /home/moi/.caché.tar /home/moi/.. .
/:
 dir = "/"
 base = ""
 ext = ""
/home/moi/:
 dir = "/home/moi/"
 base = ""
 ext = ""
/home/moi/fichier:
 dir = "/home/moi/"
 base = "fichier"
 ext = ""
/home/moi/fichier.tar:
 dir = "/home/moi/"
 base = "fichier"
 ext = "goudron"
/home/me/file.tar.gz:
 dir = "/home/moi/"
 base = "fichier.tar"
 ext = "gz"
/home/moi/.caché:
 dir = "/home/moi/"
 base = ".caché"
 ext = ""
/home/moi/.caché.tar:
 dir = "/home/moi/"
 base = ".caché"
 ext = "goudron"
/home/moi/..:
 dir = "/home/moi/"
 base = ".."
 ext = ""
.:
 dir = ""
 base = "."
 ext = ""

39voto

Kebabbert Points 79

Mellen, écrit dans un commentaire sur un blog:

À l'aide de bash il y a aussi ${file%.*} pour obtenir le nom du fichier sans l'extension et de l' ${file##*.} pour obtenir l'extension. I. e.

file="thisfile.txt"
echo "filename: ${file%.*}"
echo "extension: ${file##*.}"

sorties:

filename: thisfile
extension: txt

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