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


Получить помощь и пообщаться с другими пользователями Ubuntu можно
на irc канале #ubuntu-ru в сети Freenode
и в Jabber конференции ubuntu@conference.jabber.ru

Автор Тема: bash скрипт wget ftp качаем в папки по датам  (Прочитано 5913 раз)

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

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 6017
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
Re: bash скрипт wget ftp качаем в папки по датам
« Ответ #15 : 11 Января 2017, 13:34:15 »
«Колдунство» легче разбирать если оно отформатировано (пусть простит меня коллега renzrv)
Код: (bash) [Выделить]
#!/bin/bash

DEST='/mnt/md1/Public/xxx'
FTP_GET="wget --user=xxloginxx --password=xxxxxx -qO - ftp.xxx.ru"

T="$(LC_ALL=C date '+%Y/%b')"

LC_ALL=C $FTP_GET |
    awk -vt=${T} '($1 "/" $2) == t {print gensub(/.*">(.+)\/<\/a>\s*$/, "\\1", 1)}' |
        while read dir
        do
    DEST_DIR="${DEST}/${T}/${dir}"
            mkdir -p "$DEST_DIR"
    ${FTP_GET}/${dir}/ |
                awk -vt=${T} '($1 "/" $2) == t {print gensub(/.*"(ftp:\/\/.+)">.*/, "\\1", 1)}' |
                   ${FTP_GET% -q*} -c -N -P "$DEST_DIR" -i -
        done

Пользователь добавил сообщение 11 Января 2017, 15:06:10:
И как на меня sed проще и быстрее awk
Код: (bash) [Выделить]
T="$(LC_ALL=C date '+%Y %b')"

… sed "/\n/P;/${T}/s#>\|/</a>#\n#g;D" |

… DEST_DIR="${DEST}/${T% *}/${T#* }/${dir}"

… sed "/\n/P;/${T}/s#href=\"\|\">#\n#g;D" |
« Последнее редактирование: 11 Января 2017, 15:09:36 от Azure »
В Linux можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 2648
    • Просмотр профиля
Re: bash скрипт wget ftp качаем в папки по датам
« Ответ #16 : 11 Января 2017, 15:35:37 »
Ладно прощаю), теперь +15 к уровню :)

aibolitr,
Цикл обрабатывает список имен директорий в корне сервера с датами модификаци текущего года и месяца.
В цикле:
   1. Создается соответствующая локальная директория.
   2. Из директории сервера загружаются и сохраняются в созданую локальную директорию файлы с датами модификаци текущего года и месяца.
Но недостатнок в том что wget на каждом файле релогинится на сервер.
Вот вариант на perl всего с одним логином:
Код: (perl) [Выделить]
#!/usr/bin/perl

use strict;
use warnings;
use Net::FTP;
use POSIX qw( strftime );

my $dest = 'полный_путь_к_директории_для_сохранения';
my $ftp_server = 'ftp.ххх.ru';
my $ftp_dir = '';
my $ftp_login = '';
my $ftp_passw = '';

-d $dest or die "Dest dir not exist";
my ($now_m, $now_y) = split " ", strftime('%m %Y', localtime);
my ($n, $f_cnt);
my %r;

sub conv_bytes {
my $b = $_[0] + 0;
my ($r, $n);
my $k = 1024;
my $m = 1048576;
my $g = 1073741824;
if    ($b >= $g) { $r = $b / $g; $n = 'G' }
elsif ($b >= $m) { $r = $b / $m; $n = 'M' }
elsif ($b >= $k) { $r = $b / $k; $n = 'K' }
else             { $r = $b;      $n = 'B' }
sprintf '%.3g %s', $r, $n;
}

my $ftp = Net::FTP->new($ftp_server, Debug => 0)
or die "Cannot connect to $ftp_server: $@";

$ftp->login($ftp_login, $ftp_passw) or die "Cannot login ", $ftp->message;
if ($ftp_dir) { $ftp->cwd($ftp_dir) or die "Cannot change working directory ", $ftp->message }

print "Просмотр директорий...\n";
for my $dir (grep {/^d/} $ftp->dir) {
$dir =~ s/.* (\S+)$/$1/;
print "$dir\n";
for my $file (grep {/^-/} $ftp->dir($dir)) {
$file =~ s/.* (\S+)$/$1/;
my $file_m_time = $ftp->mdtm("$dir/$file");

next unless ($file_m_time);
my ($m_m, $m_y) = split " ", strftime('%m %Y', localtime($file_m_time));

next unless ($m_m eq $now_m && $m_y eq $now_y);
print "     $file\n";
$r{$dir}{$file} = '';
$f_cnt++;
}
}

print "\nНе найдено файлов.\n" and exit if (keys %r == 0);
$ftp->binary;

print "\nЗагрузка файлов...\n";
for my $dir (keys %r) {
print "Директория $dir\n";
my $dest_path = "$dest/$dir";
-d $dest_path
or mkdir $dest_path, 0755
or die "Ошибка при попытке создания директории $dir";
for my $file (keys %{$r{$dir}}) {
++$n;
my $s = &conv_bytes($ftp->size("$dir/$file"));
print "     файл: $file ($n из $f_cnt, $s)...\n";
$ftp->get("$dir/$file", "$dest_path/$file");
}
}

$ftp->quit;

« Последнее редактирование: 16 Января 2017, 13:01:25 от renzrv »

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 2648
    • Просмотр профиля
Re: bash скрипт wget ftp качаем в папки по датам
« Ответ #17 : 16 Января 2017, 15:49:54 »
Azure,
Мои фильтры дир./файлов на awk и ваши:
Код: (bash) [Выделить]
sed "/\n/P;/${T}/s#>\|/</a>#\n#g;D"
sed "/\n/P;/${T}/s#href=\"\|\">#\n#g;D"
неправильно фильтруют.

(Нажмите, чтобы показать/скрыть)

Исправленый:
Код: (bash) [Выделить]
#!/bin/bash
     
DEST='/mnt/md1/Public/xxx'
FTP_GET="wget --user=xxxxx --password=xxxxx -qO - ftp.xxx.ru"

T="$(LC_ALL=C date '+%Y %b')"

LC_ALL=C ${FTP_GET}/ \
| awk -vt="$T" '($1 " " $2 == t && /^[^<]+ Directory\s+</){print gensub(/.*>([^/]+)\/<\/a>\s*$/, "\\1", 1)}' \
| while read dir
do
DEST_DIR="${DEST}/${T% *}/${T#* }/${dir}"
mkdir -p "$DEST_DIR"
LC_ALL=C ${FTP_GET}/${dir}/ \
           | awk -vt="$T" '($1 " " $2 == t && /^[^<]+ File\s+</){print gensub(/.*<a href="([^"]+)".*$/, "\\1", 1)}' \
           | ${FTP_GET% -q*} -c -N -P "$DEST_DIR" -i -
done

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 6017
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
Re: bash скрипт wget ftp качаем в папки по датам
« Ответ #18 : 16 Января 2017, 19:16:01 »
неправильно фильтруют
С неправильно поставленной задачей  имеете неправильный рецепт
Код: (bash) [Выделить]
sed "/\n/P;/${T}.*Directory/s#>\|/</a>#\n#g;D"
sed "/\n/P;/${T}.*Directory/s#href=\"\|\">#\n#g;D"
В Linux можно сделать ВСЁ что угодно, достаточно знать КАК !

 

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