Форум русскоязычного сообщества Ubuntu


Увидели сообщение с непонятной ссылкой, спам, непристойность или оскорбление?
Воспользуйтесь ссылкой «Сообщить модератору» рядом с сообщением!

Автор Тема: BASH: Скрипт сортировки файлов  (Прочитано 9187 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн FluffyMan

  • Автор темы
  • Активист
  • *
  • Сообщений: 276
  • Debian 6
    • Просмотр профиля
BASH: Скрипт сортировки файлов
« : 10 Января 2011, 23:21:32 »
Всем доброго времени суток. Вобщем, возникла у меня идея написать скрипт для сортировки файлов из директории "Загрузки" в директории "видео", "музыка", "документы" и "картинки" в зависимости от формата файла-источника. Первая версия скрипта моего была банальной и простой до ужаса:
#!/bin/bash
dir="/home/testuser/Загрузки"
{
mv $dir/{*.mp3,*.ogg} /home/testuser/Музыка
mv $dir/{*.avi,*.vob,*.flv,*.wmv} /home/testuser/Видео
mv $dir/{*.png,*.jpg,*.gif,*.bmp} /home/testuser/Картинки
mv $dir/{*.odt,*.pdf,*.doc,*.djvu} /home/testuser/Документы
} &>/dev/null

то есть тупо перемещала все файлы нужного формата в нужную мне папку. даже если их там и не было. а все сообщения я выводил в устройство "нул", чтобы не мозолило глаза в консоли при выполнении команды скрипта.

следущий шаг был таков:

#!/bin/bash
dir="/home/testuser/Загрузки"
f=$(ls /home/testuser/Загрузки/)
{       case "$f" in
                *.avi|*.flv|*.wmv|*.vob)
                mv -v $dir/"$f" /home/testuser/Видео
        ;;
                *.jpg|*.png|*.gif|*.bmp)
                mv -v $dir/"$f" /home/testuser/Картинки
        ;;
                *.doc|*.djvu|*.odt|*.pdf)
                mv -v $dir/"$f" /home/testuser/Документы
        ;;
                *.mp3|*.ogg)
                mv -v $dir/"$f" /home/testuser/Музыка
         ;;
        esac
}

здесь командой ls проверяю директорию-источник и присваиваю результат команды переменной. все работает отлично. НО если в дирректории-источнике более чем 1 файл, то скрипт отказывается работать.

ВОПРОС: если ls выдает несколько файлов, то как мне переменной присвоить ТОЛЬКО первое имя файла и его обрабатывать в скрипте? а далее в цикле файл за файлом обрабатывать и сортировать, пока команда ls не будет ругаться на то, что уже нечего выдавать.

Axa-Ru

  • Гость
Re: BASH: Скрипт сортировки файлов
« Ответ #1 : 11 Января 2011, 00:10:48 »
for file in $( ls )
do
  if [ -f $file ]
  then
    ls $file
  fi
done

Оффлайн FluffyMan

  • Автор темы
  • Активист
  • *
  • Сообщений: 276
  • Debian 6
    • Просмотр профиля
Re: BASH: Скрипт сортировки файлов
« Ответ #2 : 11 Января 2011, 00:30:19 »
не могли бы Вы раскаментировать этот код? я новичек в баш скриптах. не совсем понятно что такое -f.
« Последнее редактирование: 11 Января 2011, 00:41:58 от Fluffy1234567890 »

Axa-Ru

  • Гость
Re: BASH: Скрипт сортировки файлов
« Ответ #3 : 11 Января 2011, 01:07:52 »
-f - тест на "регулярный" файл.

Цитировать
-b File is block special device (for files like /dev/hda1)
-c File is character special (for files like /dev/tty)
-d File is a directory
-e File exists
-f File is a regular file
-g File has its set-group-ID bit set
-h File is a symbolic link (same as -L)
-G File is owned by the effective group ID
-k File has its sticky bit set
-L File is a symbolic link (same as -h)
-O File is owned by the effective user ID
-p File is a named pipe
-r File is readable
-s File has a size greater than zero
-S File is a socket
-u File has its set-user-ID bit set
-w File is writable
-x File is executable

Есть такая книжка "bash Cookbook" - там пара сотен примеров использования bash скриптов

Оффлайн FluffyMan

  • Автор темы
  • Активист
  • *
  • Сообщений: 276
  • Debian 6
    • Просмотр профиля
Re: BASH: Скрипт сортировки файлов
« Ответ #4 : 11 Января 2011, 01:39:28 »
#!/bin/bash
dir="/home/testuser/Загрузки"
for file in $( ls /home/testuser/Загрузки ) # переменной file присваиваем значение от 0 до кол-ва файлов в папке "Загрузки" (кол-во итераций цикла как понял)
do                      
  if [ -f $file ] # если файл "регулярный" (я так понимаю "верхний" в списке)
  then # то
    ls $file # отобразить этот файл? этого я не понял.
       case "$file" in
                *.avi|*.flv|*.wmv|*.vob)
                mv -v $dir/"$file" /home/testuser/Видео
        ;;
                *.jpg|*.png|*.gif|*.bmp)
                mv -v $dir/"$file" /home/testuser/Картинки
        ;;
                *.doc|*.djvu|*.odt|*.pdf)
                mv -v $dir/"$file" /home/testuser/Документы
        ;;
                *.mp3|*.ogg)
                mv -v $dir/"$file" /home/testuser/Музыка
         ;;
        esac
fi                    
done                    
     

поправьте меня, если гдето неверно
« Последнее редактирование: 11 Января 2011, 01:55:40 от Fluffy1234567890 »

Axa-Ru

  • Гость
Re: BASH: Скрипт сортировки файлов
« Ответ #5 : 11 Января 2011, 01:55:20 »
Аккуратное форматирование - залог успеха.
Вы забыли завершающи "done" для внешнего цикла "for"

Оффлайн FluffyMan

  • Автор темы
  • Активист
  • *
  • Сообщений: 276
  • Debian 6
    • Просмотр профиля
Re: BASH: Скрипт сортировки файлов
« Ответ #6 : 11 Января 2011, 01:58:33 »
нет, не забыл. done у меня в самой последней строке кода. или я чего-то еще не понял?

Axa-Ru

  • Гость
Re: BASH: Скрипт сортировки файлов
« Ответ #7 : 11 Января 2011, 02:05:30 »
#!/bin/bash

for file in $( ls )#!/bin/bash
  dir="/home/testuser/Загрузки"
  for file in $( ls /home/testuser/Загрузки ) # переменной file присваиваем значение от 0 до кол-ва файлов в папке "Загрузки" (кол-во итераций цикла как понял)
  do                      
    if [ -f $file ] # если файл "регулярный" (я так понимаю "верхний" в списке)
    then # то
      ls $file # отобразить этот файл? этого я не понял.
        case "$file" in
          *.avi|*.flv|*.wmv|*.vob)
            mv -v $dir/"$file" /home/testuser/Видео
            ;;
          *.jpg|*.png|*.gif|*.bmp)
            mv -v $dir/"$file" /home/testuser/Картинки
            ;;
          *.doc|*.djvu|*.odt|*.pdf)
            mv -v $dir/"$file" /home/testuser/Документы
            ;;
          *.mp3|*.ogg)
            mv -v $dir/"$file" /home/testuser/Музыка
            ;;
        esac
    fi
  done
done
Регулярный - это не директория, не файл-устройство
« Последнее редактирование: 11 Января 2011, 02:08:10 от Axa-Ru »

Оффлайн FluffyMan

  • Автор темы
  • Активист
  • *
  • Сообщений: 276
  • Debian 6
    • Просмотр профиля
Re: BASH: Скрипт сортировки файлов
« Ответ #8 : 11 Января 2011, 02:50:22 »
#!/bin/bash

for file in $(ls /home/fluffy/Загрузки)
 do
    dir="/home/fluffy/Загрузки"
    for file in $(ls /home/fluffy/Загрузки)
  do
    if [ -f $file ]
    then
    ls $file
        case "$file" in
          *.avi|*.flv|*.wmv|*.vob)
            mv -v $dir/"$file" /home/fluffy/Видео
            ;;
          *.jpg|*.png|*.gif|*.bmp)
            mv -v $dir/"$file" /home/fluffy/Картинки
            ;;
          *.doc|*.djvu|*.odt|*.pdf)
            mv -v $dir/"$file" /home/fluffy/Документы
            ;;
          *.mp3|*.ogg)
            mv -v $dir/"$file" /home/testuser/Музыка
            ;;
        esac
    fi
   done
done
 

ничего не могу понять. скрипт не работает. то есть выполняется без ошибок, но результата нету. файлы мп3 как были в папке "Загрузки", так они там и остались

Оффлайн smaharbA

  • Участник
  • *
  • Сообщений: 220
    • Просмотр профиля
Re: BASH: Скрипт сортировки файлов
« Ответ #9 : 11 Января 2011, 07:03:12 »
Весь "скрипт"
find ~/Загрузки -type f \( -iregex '.*\.\(jpg\|png\|bmp\|gif\)$' -exec cp -f -v {} ~/Картинки \; -o \
                           -iregex '.*\.\(avi\|mov\|flv\|wmv\)$' -exec cp -f -v {} ~/Видео \; -o \
                           -iregex '.*\.\(doc.*\|xls.*\|od.\|pdf.*\|djvu\)$' -exec cp -f -v {} ~/Документы \; -o \
                           -iregex '.*\.\(mp3\|ogg\)$' -exec cp -f -v {} ~/Музыка \; \)
но как и все выше посты решение крайне примитивное и такое же не верное, как и выше
« Последнее редактирование: 11 Января 2011, 07:19:53 от smaharbA »
Я конечно далек от мысли...(с)

Axa-Ru

  • Гость
Re: BASH: Скрипт сортировки файлов
« Ответ #10 : 11 Января 2011, 07:41:41 »
Помещаете скрипт в каталог, куда идут загрузки. И оттуда же вызываете.
Вашей версии скрипта был примене "прием" copy-past без осмысления.
Книжки Вам нужны. Рекомендую:
1. Pro Bash Programming: Scripting the GNU/Linux Shell. Copyright © 2009 by Chris F.A. Johnson
2. bash CookbookTM by Carl Albing, JP Vossen, and Cameron Newham. Copyright © 2007 O’Reilly Media, Inc. All rights reserved.

#!/bin/bash

VIDEO=$HOME"/Downloads/Видео"
PICTURE=$HOME"/Downloads/Картинки"
DOCS=$HOME"/Downloads/Документы"
MUSAC=$HOME"/Downloads/Музыка"

# проверяем, существуют ли каталоги. Если нет - создаем их
if [ ! -e $VIDEO ]
then
  mkdir -p $VIDEO
fi

if [ ! -e $PICTURE ]
then
  mkdir -p $PICTURE
fi

if [ ! -e $DOCS ]
then
  mkdir -p $DOCS
fi

if [ ! -e $MUSAC ]
then
  mkdir -p $MUSAC
fi


for file in *
do                      
  if [ -f $file ] # если файл "регулярный" (не директория и не файл-устройство)
  then # то
    case "$file" in
      *.avi|*.flv|*.wmv|*.vob)
        mv -v "$file" $VIDEO
        ;;
      *.jpg|*.png|*.gif|*.bmp)
        mv -v "$file" $PICTURE
        ;;
      *.doc|*.djvu|*.odt|*.pdf)
        mv -v "$file" $DOCS
        ;;
      *.mp3|*.ogg)
        mv -v "$file" $MUSAC
        ;;
    esac
  fi
done
« Последнее редактирование: 11 Января 2011, 09:28:35 от Axa-Ru »

Оффлайн FluffyMan

  • Автор темы
  • Активист
  • *
  • Сообщений: 276
  • Debian 6
    • Просмотр профиля
Re: BASH: Скрипт сортировки файлов
« Ответ #11 : 11 Января 2011, 17:45:02 »
Axa-Ru, Вы немного не поняли. Папки "Видео", "Музыка" и тд. уже существуют проверять их наличие не нужно. нужно в них закидывать файлы. Если я файл со скриптом положу в /usr/local/bin и буду в терминале запускать его одной командой, я думаю, смысл не изменится.
#!/bin/bash
dir="/home/fluffy/Загрузки"
for file in *
do
        if [ -f $file ]; then
        case "$file" in
        *.avi|*.flv|*.wmv|*.vob)
                mv -v $dir/"$file" /home/fluffy/Видео
        ;;
        *.jpg|*.png|*.gif|*.bmp)
                mv -v $dir/"$file" /home/fluffy/Картинки
        ;;
        *.doc|*.djvu|*.odt|*.pdf)
                mv -v $dir/"$file" /home/fluffy/Документы
        ;;
        *.mp3|*.ogg)
                mv -v $dir/"$file" /home/fluffy/Музыка
         ;;
        esac
fi
done

В коде убрал область проверки и создания папок.
при запуске скрипта выдает следущее:
/usr/local/bin/sort: строка 5: [: Рабочий: ожидается использование бинарного оператора
спасибо, за отклик в такое позднее время)) видимо рано я полез в такую глубь баш-программирования. буду читать книги

Axa-Ru

  • Гость
Re: BASH: Скрипт сортировки файлов
« Ответ #12 : 11 Января 2011, 18:13:42 »
Да оставте проверку папок.
Просто, где определябтся переменные VIDEO, PICTURE ... поставте реальные пути.
У меня все это работало.

Как второй вариант (кстати достаточно неплохой) попробуйте скрипт smaharbA

И напоследок, Вы опять наделали массу ошибок из-за незнания базовых принципов.

Удачи в изучении bash.
« Последнее редактирование: 11 Января 2011, 18:21:15 от Axa-Ru »

Оффлайн FluffyMan

  • Автор темы
  • Активист
  • *
  • Сообщений: 276
  • Debian 6
    • Просмотр профиля
Re: BASH: Скрипт сортировки файлов
« Ответ #13 : 11 Января 2011, 22:03:12 »
Ваш скрипт не работает. Все вернул как в Вашем варианте - тот же результат. спасибо за советы

Оффлайн gaudin

  • Участник
  • *
  • Сообщений: 227
    • Просмотр профиля
Re: BASH: Скрипт сортировки файлов
« Ответ #14 : 17 Января 2011, 23:42:09 »
Попробуй мой вариант, переносит файлы любого количества.

#!/bin/bash
# Сортирует файлы в текущей директории
# Переносит из текущей директории файлы *.flv в директорию flv
for i in *.flv ; do
   mv -f "$i" ~/flv >/dev/null 2>&1
done
# Переносит из текущей директории файлы *.pdf в директорию pdf
for k in *.pdf ; do
   mv -f "$k" ~/Документы/различные\ документы >/dev/null 2>&1
done
Ubuntu 10.04.01 ядро 2.6.37-12

 

Страница сгенерирована за 0.022 секунд. Запросов: 22.