Как проверить расширение имени файла в скрипте bash? - PullRequest
136 голосов
/ 02 января 2009

Я пишу сценарий ночной сборки в bash.
Все хорошо и прекрасно, за исключением одной маленькой загвоздки:


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

Моя проблема - определить расширение файла и затем действовать соответственно. Я знаю, что проблема в операторе if, проверяющем txt-файл.

Как определить, имеет ли файл суффикс .txt?

Ответы [ 10 ]

224 голосов
/ 02 января 2009

Марка

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

как это:

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

То есть в двойных скобках и без кавычек.

Правая сторона == является шаблоном оболочки. Если вам нужно регулярное выражение, используйте =~ затем.

199 голосов
/ 02 января 2009

Я думаю, что вы хотите сказать: "Последние четыре символа $ file равны .txt?" Если это так, вы можете использовать следующее:

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

Обратите внимание, что требуется пробел между file: и -4, поскольку модификатор ': -' означает что-то другое.

25 голосов
/ 02 января 2009

Вы просто не можете быть уверены в системе Unix, что TXT-файл действительно является текстовым файлом. Лучше всего использовать файл. Возможно попробуйте использовать:

file -ib "$file"

Затем вы можете использовать список типов MIME для сравнения или анализа первой части MIME, где вы получаете такие вещи, как «текст», «приложение» и т. Д.

24 голосов
/ 02 января 2009

Вы можете использовать команду «file», если вы действительно хотите узнать информацию о файле, а не полагаться на расширения.

Если вы чувствуете себя комфортно при использовании расширения, вы можете использовать grep, чтобы увидеть, соответствует ли оно.

14 голосов
/ 03 августа 2011

Вы также можете сделать:

   if [ "${FILE##*.}" = "txt" ]; then
       # operation for txt files here
   fi
8 голосов
/ 29 декабря 2012

Аналогично «файлу», используйте немного более простой «mimetype -b», который будет работать независимо от расширения файла.

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

Редактировать: вам может потребоваться установить libfile-mimeinfo-perl в вашей системе, если mimetype недоступен

3 голосов
/ 01 апреля 2011

Я написал сценарий bash, который просматривает тип файла, затем копирует его в какое-то место, и я использую его для просмотра видео, которые я смотрел онлайн, из своего кэша 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"&

Он использует идеи, аналогичные представленным здесь, надеюсь, это кому-нибудь пригодится.

2 голосов
/ 26 января 2017

Правильный ответ о том, как получить расширение, доступное для имени файла в linux:

${strFileName##*\\.} 

Пример печати всех расширений файлов в каталоге

for fname in $(find . -maxdepth 1 -type f) # only regular file in the current dir
    do  echo ${fname##*\.} #print extensions 
done
2 голосов
/ 03 августа 2011

Я думаю, что '$PATH_TO_SOMEWHERE' это что-то вроде '<directory>/*'.

В этом случае я бы изменил код на:

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

Если вы хотите сделать что-то более сложное с именами каталогов и текстовых файлов, вы можете:

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

Если в именах файлов есть пробелы, вы можете:

find <directory> -maxdepth 1 -type d | xargs ...
find <directory> -maxdepth 1 -type f -name "*.txt" | xargs ...
1 голос
/ 04 октября 2013

Мой взгляд на это с разрезом

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

Мое восприятие с помощью awk будет примерно таким:

>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
...