Вернуться   W&PBBS > Software > Unix/Linux/BSD
Имя
Пароль
FAQ Пометить все разделы прочитанными



Ответ
Опции темы
Старый 04-11-2007, 18:34 Ссылка на пост    #1
shr_eax
Серфер
 
shr_eax


Сообщений: 395
На форуме с: 07.04.05
Провел: 5д. 11ч. 44мин.

[?] Проверка обновлений и их "раскидывание" по папкам

Дано:
Есть раздел FISH в котором постоянно добавляются (иногда и удаляются) файлы и папки (конкретно - вручную отбираемые файлы со спутниковой рыбалки).

Требуется:
Периодически проверяя содержимое раздела FISH, создавать в другом разделе FISH_NEW структуру каталогов и символические ссылки на вновь появляющиеся файлы и папки из раздела FISH.
В FISH_NEW новые папки и файлы должны помещаться в корневые папки вида "ГГ-ММ-ДД" (т.е. папка - значение текущей даты) и соответственно отбираться по критерию "то что появилось с последней проверки на текущий момент".

Есть ли готовые решения данной задачи?

Если нет (скорее всего), то я написал небольшой shell-скрипт с использованием find+sort/comm/awk и хранением списка файлов в текстовом виде. Но есть проблема - comm срабатывает на различие строк с привязкой к их позициям. Требуется утилита (или скрипт) которые бы убирали строки из первого файла, которые есть во втором.
shr_eax вне форума   Вставить выделенное      Ответить с цитированием
Старый 05-11-2007, 01:08 Ссылка на пост    #2
redflag
Серфер


Сообщений: 12
На форуме с: 02.10.07
Провел: 5д. 11ч. 36мин.

Цитата: > Требуется утилита (или скрипт) которые бы убирали строки из первого файла, которые есть во втором.
не без помощи bash cookbook получилось вот такое решение
Код:
$ cat left                                                                             
record_01
record_02.left only
record_03
record_05.differ
record_06
record_07
record_08
record_09
record_10
$ cat right                                                                            
cat right
record_01
record_02
record_04
record_05
record_06.differ
record_07
record_08
record_09.right only
record_10
$ diff  --unchanged-line-format= --new-line-format= left right
record_02.left only
record_03
record_05.differ
record_06
record_09
$
redflag вне форума   Вставить выделенное      Ответить с цитированием
Старый 05-11-2007, 17:08 Ссылка на пост    #3
shr_eax
Серфер
 
shr_eax


Сообщений: 395
На форуме с: 07.04.05
Провел: 5д. 11ч. 44мин.

Хе, какие хитрые параметры у diff - заханырили так, шо найти можно только глубоко в недрах info. Спасибо, всё работает
shr_eax вне форума   Вставить выделенное      Ответить с цитированием
Старый 19-09-2009, 22:02 Ссылка на пост    #4
shr_eax
Серфер
 
shr_eax


Сообщений: 395
На форуме с: 07.04.05
Провел: 5д. 11ч. 44мин.

Вобщем, получилось сделать нормально работающий скрипт. Из требований - нужны утилиты sed, awk, find, bash (возможно сработает на sh, но не проверял).

Параметры, которые следует менять:
WHATSNEW_HOME - папка где будет лежать файл с базой по файлам (а также временные файлы при работе скрипта)
TMPCHK - название временного файла
CURCHK - название файла, где будет храниться база по файлам
LINKS - папка, в которой будут создаваться симлинки на новые файлы
CHECK_DIR - собственно, папка, которую проверяют на обновления (у меня это папка с кучей симлинков на смонтированные разделы, основная шара в самбе)

Также, если необходимо исключить некоторые папки на проверку обновлений, то следует поправить части кода, где находится:
Код:
    find -L "$CHECK_DIR" \
        -not -path '/mnt/_share/fish/fish_сырая/*' \
        -not -path '/mnt/_share/nevod_по_датам/*' \
        -type f > "$CURCHK"
Здесь, /mnt/_share/fish/fish_сырая/* и /mnt/_share/nevod_по_датам/* - это папки, которые исключаются из проверки. Если исключений не надо - просто уберите эти две строки, оставив:
Код:
    find -L "$CHECK_DIR" \
        -type f > "$CURCHK"


Сам скрипт:
Код:
#!/bin/bash

DATE=`date +%y-%m-%d`

WHATSNEW_HOME="/etc/whatsnew"
TMPCHK="$WHATSNEW_HOME/nevod_tmpchk"
CURCHK="$WHATSNEW_HOME/nevod_curchk"

LINKS="/mnt/_share/nevod_по_датам"
CHECK_DIR="/mnt/_share"

if test ! -d "$LINKS" ; then
    echo "No links basedir!"
    exit
fi

if test ! -d "$CHECK_DIR" ; then
    echo "No check dir!"
    exit
fi

LINKS_BASEDIR="$LINKS/$DATE/"
TMP2="$WHATSNEW_HOME/tmp2"

# Если до этого совсем не было проверок - создаём первую и выходим
if  test ! -f "$CURCHK" ; then
    echo "Creating new curchk.."
    find -L "$CHECK_DIR" \
        -not -path '/mnt/_share/fish/fish_сырая/*' \
        -not -path '/mnt/_share/nevod_по_датам/*' \
        -type f > "$CURCHK"
    exit
fi

if  test ! -f "$TMPCHK" ; then
    rm -f "$TMPCHK"
fi

CHECK_DIR_LNG=`awk 'BEGIN {print length("'$CHECK_DIR'")+1}'`

echo "Checking current state.."
find -L "$CHECK_DIR" \
    -not -path '/mnt/_share/fish/fish_сырая/*' \
    -not -path '/mnt/_share/nevod_по_датам/*' \
    -type f > "$TMPCHK"

# Если текущее состояние такое же как и прежде - выходим
echo "Check for difference.."
# Создадим временный файл с различиями для ускорения обработки
if diff  --unchanged-line-format= --new-line-format= --speed-large-files "$TMPCHK" "$CURCHK" > "$TMP2" ; then
    rm -f "$TMPCHK"
    rm -f "$TMP2"
    echo "There's no difference"
    exit
fi

#ЗЫ: \42 это "
#ЗЫ: \47 это '

# Создаём структуру директорий
echo "Creating directories.."
cat "$TMP2" | \
    # Заменяем все ' на '\''
    sed 's/'\''/'\''\\'\'\''/g' | \
    # Откидываем имя файла и оставляем только путь
    awk '{system("dirname \47"$0"\47")}' | \
    # Делаем пути уникальными
    uniq | \
    sed 's/'\''/'\''\\'\'\''/g' | \
    # Собственно создаём каталог
    awk '{system("mkdir -p \47'$LINKS_BASEDIR'"substr($0,'$CHECK_DIR_LNG')"\47")}'

# Создаём символические ссылки
echo "Creating symbolic links.."
cat "$TMP2" | \
    sed 's/'\''/'\''\\'\'\''/g' | \
    awk '{system("ln -s \47"$0"\47 \47'$LINKS_BASEDIR'"substr($0,'$CHECK_DIR_LNG')"\47")}'

rm -f "$TMP2"
mv -f $TMPCHK $CURCHK

Как он работает - при первом запуске создаёт базу и выходит. При повторном и последующих запусках создаёт временную базу, сравнивает с основной, различия (новые файлы) появляются в папке LINKS, в которой сначала создаётся подпапка с именем вроде 09-09-19 (т.е. 19 сентября 2009, дата проверки), а в ней подпапки до нового файла и симлинк на него.
Т.е. например, в папке /mnt/_share/mp3/__unsorted_7/_pump появился новый файл Markus_Schulz_-_Global_DJ_Broadcast_2009.07.23.mp3, тогда в LINKS директории будут создано следующее дерево папок: /mnt/_share/nevod_по_датам/09-09-19/mp3/__unsorted_7/_pump. Внутри последней будет лежать симлинк:
Код:
Markus_Schulz_-_Global_DJ_Broadcast_2009.07.23.mp3 -> /mnt/_share/mp3/__unsorted_7/_pump/Markus_Schulz_-_Global_DJ_Broadcast_2009.07.23.mp3

Скрипт вешаем по крону, но только чтобы не особо часто выполнялся, т.к. винты сильно напрягаются во время проверки.

Редактировалось shr_eax
19-09-2009 22:22.
shr_eax вне форума   Вставить выделенное      Ответить с цитированием
Ответ


Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра Оценка этой теме
Оценка этой теме:

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

vB коды Вкл.
[IMG] код Вкл.
Быстрый переход





Предупреждение: Никакого детского порно в запросах и ссылках.
Любое упоминание детского порно в контексте будет пресекаться.


Часовой пояс GMT +4, серверное время: 03:57.