Как проверить расширение имени файла в bash-скрипте?
Вопрос
Я пишу сценарий ночной сборки в 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?
Решение
Я думаю, вы хотите сказать: "Равны ли последние четыре символа $file .txt
?" Если да, то вы можете использовать следующее:
if [ ${file: -4} == ".txt" ]
Обратите внимание , что пространство между file:
и -4
требуется, так как модификатор ':-' означает что-то другое.
Другие советы
Сделать
if [ "$file" == "*.txt" ]
вот так:
if [[ $file == *.txt ]]
То есть двойные скобки и никаких кавычек.
Правая сторона ==
это шаблон оболочки.Если вам нужно регулярное выражение, используйте =~
затем.
Вы просто не можете быть уверены в системе Unix, что файл .txt действительно является текстовым файлом.Лучше всего использовать "файл".Может быть, попробовать использовать:
file -ib "$file"
Затем вы можете использовать список типов MIME для сопоставления или анализа первой части MIME, где вы получаете такие вещи, как "текст", "приложение" и т.д.
Вы можете использовать команду "файл", если вы действительно хотите узнать информацию о файле, а не полагаться на расширения.
Если вы чувствуете себя комфортно при использовании расширения, вы можете использовать grep, чтобы проверить, соответствует ли оно.
Вы также могли бы сделать:
if [ "${FILE##*.}" = "txt" ]; then
# operation for txt files here
fi
Подобно "файлу", используйте немного более простой "mimetype -b", который будет работать независимо от расширения файла.
if [ $(mimetype -b "$MyFile") == "text/plain" ]
then
echo "this is a text file"
fi
Редактировать:возможно, вам потребуется установить libfile-mimeinfo-perl в вашей системе, если mimetype недоступен
Я написал скрипт 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"&
В нем используются идеи, аналогичные представленным здесь, надеюсь, это кому-то поможет.
Я предполагаю, что '$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 ...
Правильный ответ о том, как использовать расширение, доступное в имени файла в linux, таков :
${strFileName##*\\.}
Пример печати всех расширений файлов в каталоге
for fname in $(find . -maxdepth 1 -type f) # only regular file in the current dir
do echo ${fname##*\.} #print extensions
done
Мой взгляд на это с огранкой
>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