web-dev-qa-db-fra.com

Comment vérifier l'extension d'un nom de fichier dans un script bash?

J'écris un script de construction nocturne à Bash.
Tout va bien, sauf un petit problème:


#!/bin/bash

for file in "$PATH_TO_SOMEWHERE"; do
      if [ -d $file ]
      then
              # do something directory-ish
      else
              if [ "$file" == "*.txt" ]       #  this is the snag
              then
                     # do something txt-ish
              fi
      fi
done;

Mon problème est de déterminer l’extension du fichier puis d’agir en conséquence. Je sais que le problème est dans la déclaration if, à la recherche d'un fichier txt.

Comment puis-je déterminer si un fichier a un suffixe .txt?

145
theman_on_vista

Je pense que vous voulez dire "Les quatre derniers caractères de $ file sont-ils égaux à .txt?" Si oui, vous pouvez utiliser les éléments suivants:

if [ ${file: -4} == ".txt" ]

Notez que l'espace entre file: et -4 est requis, car le modificateur ': -' signifie quelque chose de différent.

211
Paul Stephenson

Make

if [ "$file" == "*.txt" ]

comme ça:

if [[ $file == *.txt ]]

C'est-à-dire des doubles crochets et pas de guillemets.

Le côté droit de == est un motif Shell. Si vous avez besoin d'une expression régulière, utilisez =~ then.

233
user49586

Sur un système Unix, vous ne pouvez pas être sûr qu'un fichier .txt est vraiment un fichier texte. Votre meilleur pari est d'utiliser "fichier". Peut-être essayer d'utiliser:

file -ib "$file"

Ensuite, vous pouvez utiliser une liste de types MIME à comparer ou analyser la première partie du MIME où vous obtenez des éléments tels que "texte", "application", etc.

25
Eldelshell

Vous pouvez utiliser la commande "fichier" si vous souhaitez réellement obtenir des informations sur le fichier plutôt que de vous fier aux extensions.

Si vous êtes à l'aise avec l'utilisation de l'extension, vous pouvez utiliser grep pour voir si elle correspond.

24
Adam Peck

Vous pouvez aussi faire:

   if [ "${FILE##*.}" = "txt" ]; then
       # operation for txt files here
   fi
14
kvz

Semblable à "fichier", utilisez le "mimetype -b" légèrement plus simple qui fonctionnera quelle que soit l'extension du fichier.

if [ $(mimetype -b "$MyFile") == "text/plain" ]
then
  echo "this is a text file"
fi

Edit: vous devrez peut-être installer libfile-mimeinfo-Perl sur votre système si le type MIME n'est pas disponible

8
dargaud

J'ai écrit un script bash qui examine le type d'un fichier, puis le copie dans un emplacement. Je l'utilise pour parcourir les vidéos que j'ai visionnées en ligne à partir de mon cache firefox:

#!/bin/bash
# flvcache script

CACHE=~/.mozilla/firefox/xxxxxxxx.default/Cache
OUTPUTDIR=~/Videos/flvs
MINFILESIZE=2M

for f in `find $CACHE -size +$MINFILESIZE`
do
    a=$(file $f | cut -f2 -d ' ')
    o=$(basename $f)
    if [ "$a" = "Macromedia" ]
        then
            cp "$f" "$OUTPUTDIR/$o"
    fi
done

nautilus  "$OUTPUTDIR"&

Il utilise des idées similaires à celles présentées ici. J'espère que cela sera utile à quelqu'un.

3
desdecode

La bonne réponse sur la façon de prendre l'extension disponible dans un nom de fichier sous linux est:

${strFileName##*\\.} 

Exemple d'impression de toutes les extensions de fichier dans un répertoire

for fname in $(find . -maxdepth 1 -type f) # only regular file in the current dir
    do  echo ${fname##*\.} #print extensions 
done
2
Albin. Com.

Je suppose que '$PATH_TO_SOMEWHERE'est quelque chose comme '<directory>/*'.

Dans ce cas, je changerais le code en:

find <directory> -maxdepth 1 -type d -exec ... \;
find <directory> -maxdepth 1 -type f -name "*.txt" -exec ... \;

Si vous voulez faire quelque chose de plus compliqué avec les noms de répertoire et de fichier texte, vous pouvez:

find <directory> -maxdepth 1 -type d | while read dir; do echo $dir; ...; done
find <directory> -maxdepth 1 -type f -name "*.txt" | while read txtfile; do echo $txtfile; ...; done

Si vous avez des espaces dans vos noms de fichiers, vous pouvez:

find <directory> -maxdepth 1 -type d | xargs ...
find <directory> -maxdepth 1 -type f -name "*.txt" | xargs ...
2
jfg956

Ma prise sur elle avec coupe

>cut -d'.' -f2<<<"hi_mom.txt"
txt

Ma prise avec awk serait quelque chose comme ce qui suit.

>MY_DATA_FILE="my_file.sql"
>FILE_EXT=$(awk -F'.' '{print $NF}' <<< $MY_DATA_FILE)
>if [ "sql" = "$FILE_EXT" ]
>then
>   echo "file is sql"
>fi

>awk -F'.' '{print $NF}' <<eof
>hi_mom.txt
>my_file.jpg
>eof
1
John Babb