risposta-alla-domanda-sullo-sviluppo-web-bd.com

Come controllare l'estensione di un nome file in uno script bash?

Sto scrivendo un copione notturno di build in bash.
Tutto bene e dandy tranne un piccolo inconveniente:


#!/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;

Il mio problema è determinare l'estensione del file e quindi agire di conseguenza. So che il problema è nell'istruzione if, che sta testando un file txt.

Come posso determinare se un file ha un suffisso .txt?

145
theman_on_vista

Penso che tu voglia dire "Gli ultimi quattro caratteri di $ file sono uguali a .txt? "In tal caso, puoi utilizzare quanto segue:

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

Si noti che lo spazio tra file: e -4 è richiesto, poiché il modificatore ': -' significa qualcosa di diverso.

211
Paul Stephenson

Make

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

come questo:

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

Cioè, doppie parentesi e senza virgolette.

Il lato destro di == è un modello Shell. Se hai bisogno di un'espressione regolare, usa =~ poi.

233
user49586

Non puoi essere sicuro su un sistema Unix, che un file .txt è veramente un file di testo. La tua scommessa migliore è usare "file". Forse prova a usare:

file -ib "$file"

Quindi è possibile utilizzare un elenco di tipi MIME per abbinare o analizzare la prima parte del MIME in cui si ottengono elementi come "testo", "applicazione", ecc.

25
Eldelshell

È possibile utilizzare il comando "file" se si desidera effettivamente trovare informazioni sul file anziché fare affidamento sulle estensioni.

Se ti senti a tuo agio con l'uso dell'estensione, puoi usare grep per vedere se corrisponde.

24
Adam Peck

Puoi anche fare:

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

Simile a 'file', usa il 'mimetype -b' leggermente più semplice che funzionerà indipendentemente dall'estensione del file.

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

Modifica: potrebbe essere necessario installare libfile-mimeinfo-Perl sul tuo sistema se il mimetype non è disponibile

8
dargaud

Ho scritto uno script bash che guarda il tipo di un file e poi lo copia in una posizione, lo uso per guardare attraverso i video che ho visto online dalla mia cache di 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"&

Usa idee simili a quelle presentate qui, spero che questo sia utile a qualcuno.

3
desdecode

La risposta corretta su come rendere l'estensione disponibile in un nome file in Linux è:

${strFileName##*\\.} 

Esempio di stampa di tutte le estensioni di file in una directory

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

Immagino che '$PATH_TO_SOMEWHERE'è qualcosa come '<directory>/*'.

In questo caso, cambierei il codice in:

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

Se vuoi fare qualcosa di più complicato con la directory e i nomi dei file di testo, puoi:

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

Se hai spazi nei nomi dei file, puoi:

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

La mia opinione su di esso con il taglio

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

La mia opinione su Awk sarebbe qualcosa di simile al seguente.

>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