The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
как сделать чтобы цикл не останавливался, !*! gorlum300, 02-Фев-14, 16:47  [смотреть все]
не так много опыта в кодинге, но попробую обьяснить.
Есть файл "test" куда периодически дописываются новые данные в виде блоков по 3 строки:
var1 frog32
var2 2013-01-014234
var3 "url"
var1 rabit1
var2 2013-01-033122
var3 "url2"
итд
Задача периодически читать этот файл и для новых данных создавать директорию по имени значения следующего после var2, куда записывать текстовый файл с именем после var1 и скачивать файл следующий после var3.

Пока у меня получился следующий скрипт, однако, он создает текстовые файлы всех значений var1 из всего файла в каждой новой директории.
Как бы сделать так, чтобы второй цикл не завершал работу, а как бы приостанавливал, и когда 1й цикл опять создает новую директорию, продолжал просматривать файл с того же места?
Или мб есть другое решение чтобы в каждой директории был только 1 текстовый файл соответствующий своему блоку данных?

#!/bin/bash

DIR1=/home/user/aaa

for i in $(grep var2 $DIR1/test|awk '{print $2}');
do mkdir $i;
cd $i;
   for name in $(grep var1 $DIR1/test|awk '{print $2}'); do
   if [ -f "$DIR1/$i/$name" ];
    then echo have;
    else
   touch $name;
   fi
   done;
   cd $DIR1;
done

  • как сделать чтобы цикл не останавливался, !*! rew, 17:44 , 02-Фев-14 (1)
    Проще запоминать последнюю отработанную строку в файле и при следующем запуске начинать с нее.
    • как сделать чтобы цикл не останавливался, !*! gorlum300, 19:16 , 02-Фев-14 (2)
      хм, а как это можно здесь сделать?
      • как сделать чтобы цикл не останавливался, !*! skb7, 22:30 , 02-Фев-14 (3)
        > хм, а как это можно здесь сделать?

        Как мне видится, скрипт должен дергаться по какому-то событию, например по cron'у, или по событию изменения файла. Скрипт должен обрабатывать строки с последней обработанной (в предыдущем запуске скрипта) и до конца файла.

        После того как обработали файл, сохранить номер последней обработанной строки:


        last_processed_line=$(wc -l file_name | awk '{print $1}')

        и сохранить в свой файл (для примера пусть будет "my_file.txt") в /var/tmp/:


        echo -n $last_processed_line >/var/tmp/my_file.txt

        При следующем вызове скрипта, считать из того временного файла номер последней обработанной строки:


        last_processed_line=$(cat /var/tmp/my_file.txt)

        Дальше надо вычислить сколько строк не обработано на данный момент:


        line_count=$(wc -l file_name | awk '{print $1}')
        not_processed_lines=$((line_count - last_processed_line))

        Вывести и обработать только необработанные строки:


        for dir_name in $(tail -n $not_processed_lines file_name | grep var2 | awk '{print $2}');
            mkdir -p $dir_name
            ....
        do
            
        done

  • как сделать чтобы цикл не останавливался, !*! михалыч, 20:53 , 03-Фев-14 (5)
    >[оверквотинг удален]
    > var1 frog32
    > var2 2013-01-014234
    > var3 "url"
    > var1 rabit1
    > var2 2013-01-033122
    > var3 "url2"
    > итд
    > Задача периодически читать этот файл и для новых данных создавать директорию по
    > имени значения следующего после var2, куда записывать текстовый файл с именем
    > после var1 и скачивать файл следующий после var3.

    Похоже как на менеджер закачек файлов по запросу.
    Попробовал на perl
    Вроде взлетает и летит ))
    Но есть подводные камни ((
    какие файлы закачиваются - большие, маленькие?
    проверять на обрыв закачки?
    что будет если закачка прервётся?

    #!/usr/bin/perl

    use strict;
    use warnings;


    my ($usr, $dir, $url);

    # корневая директория
    my $r_dir = "/tmp";
    # дополняемый файл
    my $file = "/tmp/txt";

    open FH, $file or die "can't open $file: $!";

    for (;;) {
        exit if (stat(FH))[3] == 0;

        while (<FH>) {
            chomp;

            if (/var1/) {
                s/^var1\s(.*)$/$1/;
                $usr = $1;
            }

            if (/var2/) {
                s/^var2\s(.*)$/$1/;
                $dir = $1;
            }

            if (/var3/) {
                s/^var3\s(.*)$/$1/;
                $url = $1;

                # название файла для закачки
                my $out = $url;
                # обрезаем его  - из "http://ya.ru" получаем ya.ru
                $out =~ s|.*/(.*)\"|$1|;

                mkdir "$r_dir/$dir";
                `touch "$r_dir/$dir/$usr"`;
                `wget -O "$r_dir/$dir/$out" $url`;
            }
        }

        sleep "1";
        seek (FH, 0, 1);
    }

    Лучше было бы писать в дополняемый файл строки массивчиками
    user date url
    типа
    frog32 2013-01-014234 "url"
    было бы гораздо надёжнее его потрошить

    • как сделать чтобы цикл не останавливался, !*! gorlum300, 23:06 , 03-Фев-14 (6)
      спасибо! похоже начинает работать, однако, у меня выдает ошибки в этом месте:
                  $out =~ s|.*/(.*)\"|$1|;

                  mkdir "$r_dir/$dir";
                  `touch "$r_dir/$dir/$usr"`;
                 `wget -O "$r_dir/$dir/$out" $url`;
      ---
      Global symbol "$out" requires explicit package name at ./workp.pl line 38.
      Global symbol "$out" requires explicit package name at ./workp.pl line 42.

      я вот неуверен, что это значит?

      > какие файлы закачиваются - большие, маленькие?
      > проверять на обрыв закачки?
      > что будет если закачка прервётся?

      закачиваются небольшие файлы по 50-500kb.
      в идеале, конечно, нужно попробовать добавить вторую попытку скачать, и в случае если закачка не идет(идет не до конца), создавать файл с именем типа warning в директории куда скачиваются файлы.

      > Лучше было бы писать в дополняемый файл строки массивчиками
      > user date url
      > типа
      > frog32 2013-01-014234 "url"
      > было бы гораздо надёжнее его потрошить

      Сейчас потестируем рабочий вариант и если будет стабильно работать, то это будет не важно.
      Но тем не менее, расскажите, почему будет надежнее?

      • как сделать чтобы цикл не останавливался, !*! михалыч, 12:23 , 04-Фев-14 (7)
        > Но тем не менее, расскажите, почему будет надежнее?

        А потому, что будет не просто всем сёстрам по серьгам, а
        будет конкретным сёстрам конкретные серьги.

        user1 2013-01-014234 http://ya.ru
        user2 2013-01-033122 http://google.ru

        Прочитал строку, а в ней сразу указано какому юзеру что и куда.
        Значения в строке файла должны быть разделены пробелами,
        url для закачки без кавычек.

        #!/usr/bin/perl

        use strict;
        use warnings;


        my ($usr, $dir, $url, $out);

        # корневая директория
        my $r_dir = "/tmp";

        # дополняемый файл вида разделён пробелами
        # user1 date url
        # user2 date url
        my $file = "/tmp/txt";

        open FH, $file or die "can't open $file: $!";

        for (;;) {
            # вываливаемся если дополняемый файл вдруг удалили или он исчез ))
            exit if (stat(FH))[3] == 0;

            while (<FH>) {
                chomp;

                # разбиваем входную строку split'ом по пробелам и складывем в массив
                my @str = split(" ", $_);

                $usr = $str[0]; # название юзера
                $dir = $str[1]; # директория по дате и времени
                $url = $str[2]; # линк для закачки файла

                $out = $url;             # выходной файл для записи в него загрузки через wget
                $out =~ s|^.*/(.*)$|$1|; # обрезаем его, делаем из http://ya.ru только ya.ru

                # создаём директорию по дате
                mkdir "$r_dir/$dir";
                # создаём файл по имени юзера
                `touch "$r_dir/$dir/$usr"`;

                # путь к исполняемому файлу wget и параметры закачки
                # wget -q (тихий режим) -t 1 (1 повтор при неудаче) -O сохранить в файл
                my $wget = "/usr/bin/wget -q -t 1 -O \"$r_dir/$dir/$out\" $url";
                # если загрузка неудачна - удаляем выходной файл и создаем файл warning
                unlink "$r_dir/$dir/$out" and `touch "$r_dir/$dir/warning"` if system $wget;
            }
            # спать. спать.. спать... ))
            sleep "1";
            # читаем файл до конца, сбрасываем флаг EOF
            seek (FH, 0, 1);
        }

        Закачиваете странички или файлы?
        Кто или что формирует дополняемый файл?

        • как сделать чтобы цикл не останавливался, !*! gorlum300, 14:55 , 04-Фев-14 (8)
          закачиваются файлы.
          файл со списком имен и урлов формируется другим скриптом.
          я его немного переделал и теперь он формирует данные в виде:

          user1 2013-01-014234 http://ya.ru http://google.com
          user2 2013-01-013311 http://ya2.ru http://google2.com

          добавился еще один урл
          Неуверен насколько правильно, но я добавил закачку второго урла в код, выдает ошибки но все работает:

          #!/usr/bin/perl
          use strict;
          use warnings;


          my ($usr, $dir, $url, $url2, $out, $out2);


          my $r_dir = "~/Downloads";


          my $file = "~/Downloads/txt";

          open FH, $file or die "can't open $file: $!";

          for (;;) {

              exit if (stat(FH))[3] == 0;

              while (<FH>) {
                  chomp;

                  my @str = split(" ", $_);

                  $usr = $str[0];
                  $dir = $str[1];
                  $url = $str[2];
                  $url2 = $str[3];

                  $out = $url;
                  $out =~ s|^.*/(.*)$|$1|;
                  $out2 = $url2;
                  $out2 =~ s|^.*/(.*)$|$1|;


                  mkdir "$r_dir/$dir";

                  `touch "$r_dir/$dir/$usr"`;

                  my $wget = "wget -q -t 1 -O \"$r_dir/$dir/$out\" $url";
                  my $wget1 = "wget -q -t 1 -O \"$r_dir/$dir/$out2\" $url2";
                  unlink "$r_dir/$dir/$out" and `touch "$r_dir/$dir/warning"` if system $wget;
                  unlink "$r_dir/$dir/$out2" and `touch "$r_dir/$dir/warning-big"` if system $wget1;
              }

              sleep "1";

              seek (FH, 0, 1);
          exit;
          }

          ошибки вида:
          Use of uninitialized value $out in substitution (s///) at ./work2.pl line 31, <FH> line 3.
          Use of uninitialized value $out2 in substitution (s///) at ./work2.pl line 33, <FH> line 3.
          Use of uninitialized value $dir in concatenation (.) or string at ./work2.pl line 36, <FH> line 3.
          Use of uninitialized value $dir in concatenation (.) or string at ./work2.pl line 38, <FH> line 3.
          Use of uninitialized value $usr in concatenation (.) or string at ./work2.pl line 38, <FH> line 3.
          Use of uninitialized value $dir in concatenation (.) or string at ./work2.pl line 40, <FH> line 3.
          Use of uninitialized value $out in concatenation (.) or string at ./work2.pl line 40, <FH> line 3.
          Use of uninitialized value $url in concatenation (.) or string at ./work2.pl line 40, <FH> line 3.
          Use of uninitialized value $dir in concatenation (.) or string at ./work2.pl line 41, <FH> line 3.
          Use of uninitialized value $out2 in concatenation (.) or string at ./work2.pl line 41, <FH> line 3.
          Use of uninitialized value $url2 in concatenation (.) or string at ./work2.pl line 41, <FH> line 3.
          wget: missing URL
          Usage: wget [OPTION]... [URL]...

          Просто интересно - насколько это критично?

          • как сделать чтобы цикл не останавливался, !*! михалыч, 16:41 , 04-Фев-14 (9) +1
            >[оверквотинг удален]
            > Use of uninitialized value $usr in concatenation (.) or string at ./work2.pl line 38, <FH> line 3.
            > Use of uninitialized value $dir in concatenation (.) or string at ./work2.pl line 40, <FH> line 3.
            > Use of uninitialized value $out in concatenation (.) or string at ./work2.pl line 40, <FH> line 3.
            > Use of uninitialized value $url in concatenation (.) or string at ./work2.pl line 40, <FH> line 3.
            > Use of uninitialized value $dir in concatenation (.) or string at ./work2.pl line 41, <FH> line 3.
            > Use of uninitialized value $out2 in concatenation (.) or string at ./work2.pl line 41, <FH> line 3.
            > Use of uninitialized value $url2 in concatenation (.) or string at ./work2.pl line 41, <FH> line 3.
            > wget: missing URL
            > Usage: wget [OPTION]... [URL]...
            > Просто интересно - насколько это критично?

            не критично
            это в результате попытки использовать неинициализированные переменные, нужно сделать проверку на существование $dir, $out, $url
            видимо попадаются строки только с юзером без dir и/или url типа
            user
            user dir

            #!/usr/bin/perl

            use strict;
            use warnings;


            my ($usr, $dir, $url, $url2, $out, $out2);

            # корневая директория
            my $r_dir = "/tmp";

            # дополняемый файл вида разделён пробелами
            # user1 date url url2
            # user2 date url url2
            my $file = "/tmp/txt";

            open FH, $file or die "can't open $file: $!";

            for (;;) {
                # вываливаемся если дополняемый файл вдруг удалили или он исчез ))
                exit if (stat(FH))[3] == 0;

                while (<FH>) {
                    chomp;

                    # разбиваем входную строку split'ом по пробелам и складывем в массив
                    my @str = split(" ", $_);

                    $usr = $str[0]; # название юзера
                    $dir = $str[1]; # директория по дате и времени
                    $url = $str[2]; # линк для закачки файла
                    $url2= $str[3]; # линк для закачки файла

                    # если нет $usr или $dir дальнейшее безсмысленно, переходим к следующей строке
                    next if !defined $usr or !defined $dir;

                    # если нет $url и $url2 дальнейшее безсмысленно, переходим к следующей строке
                    next if !defined $url and !defined $url2;

                    # создаём директорию по дате
                    mkdir "$r_dir/$dir";
                    # создаём файл по имени юзера
                    `touch "$r_dir/$dir/$usr"`;

                    # если переменная $url определена - делаем вещи
                    if (defined $url) {
                        $out = $url;             # выходной файл для записи в него загрузки через wget
                        $out =~ s|^.*/(.*)$|$1|; # обрезаем его, делаем из http://ya.ru только ya.ru

                        # путь к исполняемому файлу wget и параметры закачки
                        # wget -q (тихий режим) -t 1 (1 повтор при неудаче) -O сохранить в файл
                        my $wget = "/usr/local/bin/wget -q -t 1 -O \"$r_dir/$dir/$out\" $url";
                        # если загрузка неудачна - удаляем выходной файл и создаем файл warning
                        unlink "$r_dir/$dir/$out" and `touch "$r_dir/$dir/warning"` if system $wget;
                    }

                    # если переменная $url2 определена - делаем вещи
                    if (defined $url2) {
                        $out2 = $url2;            # выходной файл для записи в него загрузки через wget
                        $out2 =~ s|^.*/(.*)$|$1|; # обрезаем его, делаем из http://ya.ru только ya.ru

                        # путь к исполняемому файлу wget и параметры закачки
                        # wget -q (тихий режим) -t 1 (1 повтор при неудаче) -O сохранить в файл
                        my $wget2 = "/usr/local/bin/wget -q -t 1 -O \"$r_dir/$dir/$out2\" $url2";
                        # если загрузка неудачна - удаляем выходной файл и создаем файл warning2
                        unlink "$r_dir/$dir/$out2" and `touch "$r_dir/$dir/warning2"` if system $wget2;
                    }
                }
                # спать. спать.. спать... ))
                sleep "1";
                # читаем файл до конца, сбрасываем флаг EOF
                seek (FH, 0, 1);
            }


            Есть ещё чо пожевать? ))
            • как сделать чтобы цикл не останавливался, !*! gorlum300, 21:37 , 04-Фев-14 (10)
              блин, спасибо большое! оно действительно работает!:)
              Еще я сейчас заметил, что в случае если в дополняемом файле значение $dir для нескольких юзеров одинаковое (это таймстемп) то все складывается в одну директорию.

              те если например:
              user1 2013-01-014234 http://ya.ru
              user2 2013-01-014234 http://google.ru

              то все летит в папку 2013-01-014234
              я думаю как бы сделать проверку для одинаковых имен и в случае если такое уже есть, то создавать такое же, но с дополнением (напр., 2013-01-014234-duble)
              что-то вроде:

                      if (-d "$dir")
                      { print "dublicate";
                      mkdir "$r_dir/$dir";
                      rename "$r_dir/$dir","$r_dir/$dir,duble";
                     `touch $r_dir/$dir,duble/$usr"`;

              • как сделать чтобы цикл не останавливался, !*! михалыч, 22:36 , 04-Фев-14 (11)
                >[оверквотинг удален]
                > то все летит в папку 2013-01-014234
                > я думаю как бы сделать проверку для одинаковых имен и в случае
                > если такое уже есть, то создавать такое же, но с дополнением
                > (напр., 2013-01-014234-duble)
                > что-то вроде:
                >         if (-d "$dir")
                >         { print "dublicate";
                >         mkdir "$r_dir/$dir";
                >         rename "$r_dir/$dir","$r_dir/$dir,duble";
                >        `touch $r_dir/$dir,duble/$usr"`;

                имя пользователя уникально?
                ну так сразу создавать директорию
                mkdir "$r_dir/$dir-$usr";
                ну и дальше по коду поправить




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру