Unix/Shell скрипт (не могу написать shell скрипт!!!)

На самом деле это единственный раздел про unix на этом форуме

Модераторы: /dev/random, Модераторы разделов

maroonchik
Сообщения: 6

Unix/Shell скрипт

Сообщение maroonchik »

Помогите пожалуйста с задачкой!c unix знакома всего неделю, поэтому не судите строго)
Задача:
Дан файл с датами "dd.mm.yyyy 24h:mi:ss" - колонка дат. Найти минимальную, максимальную дату и разницу между ними в секундах. Можно считать, что все даты не менее 01.12.2006 00:00:00
Замечание к задаче:
В SunOS awk это nawk.
Результат должен быть оформлен как shell скрипт, первый параметр которого – имя файла, который подается на вход.
Операционка: XP Proff
Вот что я нашла на других форумах, но это perl...
работает вроде правильно, находит max и min дату, выводит разницу в секундах, но время ставит в том, и другом случае не max и не min, а случайное!!!!!!
по логике надо сделать еще как то сортировку по времени!в этом и проблема, у меня это никак не получается(((

Код: Выделить всё

eval

'exec perl -S $0 ${1+"$@"}' if 0;
open(INFILE,"<","5.txt");
my
%dates;
while(<INFILE>){
chomp;
/(\d+)\.(\d+)\.(\d+)\s+(\d+):\d+):\d+)/;
$dates{join(":",($3,$2,$1,$4,$5,$6))}=$_;
}
close
INFILE;
my @sorted_dates=sort keys %dates;
print "Max date:
$dates{$sorted_dates[$#sorted_dates]}\n";
print "Min date:
$dates{$sorted_dates[0]}\n";
my($ymax,$monmax,$dmax,$hmax,$minmax,$smax)=split
/:/,$sorted_dates[$#sorted_dates];
my($ymin,$monmin,$dmin,$hmin,$minmin,$smin)=split
/:/,$sorted_dates[0];
print "Diff secs:
",((((($ymax-$ymin)*12+($monmax-$monmin))*30+($dmax-$dmin))*24+($hmax-$hmin))*60+($minmax-$minmin))*60+($smax-$smin),"\n";


5.txt - файл из которого берутся даты
Дат max и min несколько,а отличаются они только по времени! т.е если есть max дата 10.06.2006 10:33 и 10.06.2006 22.15, то вывести надо 10.06.2006 22:15 с максимальным временем.
Спасибо сказали:
Аватара пользователя
diesel
Бывший модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian

Re: Unix/Shell скрипт

Сообщение diesel »

maroonchik , не надо плодить клонов, все апдейты по одному вопросу в один топик пожалуйста. код надо выделять тэгом code.
Спасибо сказали:
maroonchik
Сообщения: 6

Re: Unix/Shell скрипт

Сообщение maroonchik »

сорри)))
Спасибо сказали:
Аватара пользователя
diesel
Бывший модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian

Re: Unix/Shell скрипт

Сообщение diesel »

Пользуясь той же логикой, что у вас(можно красивее и правильней, но думать не хочется):

Код: Выделить всё

diesel@indie:~/scripts$ cat tmp
01.12.2006 00:00:00
01.12.2007 00:00:00
01.12.2006 00:00:02
01.12.2008 00:00:00
01.12.2007 00:00:23
diesel@indie:~/scripts$ ./time.pl tmp
Max date: 01.12.2008 00:00:00
Min date: 01.12.2006 00:00:00
Diff secs:
62208000
diesel@indie:~/scripts$ cat time.pl
#!/usr/bin/perl
use strict;
use warnings;

my @dates;
while(<>){
    chomp;
    /(\d+)\.(\d+)\.(\d+)\s+(\d+):(\d+):(\d+)/;
    push @dates, join(":",($3,$2,$1,$4,$5,$6))
}
my @sorted_dates=sort @dates;

my $max = $sorted_dates[$#sorted_dates];
my $min = $sorted_dates[0];

my ($ymax,$monmax,$dmax,$hmax,$minmax,$smax)=split(/:/,$max);
my ($ymin,$monmin,$dmin,$hmin,$minmin,$smin)=split(/:/,$min);

$max =~    s/(\d+):(\d+):(\d+):(\d+):(\d+):(\d+)/$3.$2.$1 $4:$5:$6/;
$min =~    s/(\d+):(\d+):(\d+):(\d+):(\d+):(\d+)/$3.$2.$1 $4:$5:$6/;
print "Max date: ",$max,"\nMin date: ",$min,"\n";

print "Diff secs:
",((((($ymax-$ymin)*12+($monmax-$monmin))*30+($dmax-$dmin))*24+($hmax-$hmin))*60+($minmax-$minmin))*60+($smax-$smin),"\n";
diesel@indie:~/scripts$
Спасибо сказали:
maroonchik
Сообщения: 6

Re: Unix/Shell скрипт

Сообщение maroonchik »

Я запускаю, а он не хочет ничего выводить...я правда подстроила под старую версию....что не так то????

Код: Выделить всё

eval
'exec perl -S $0 ${1+"$@"}' if 0;
open(INFILE,"<","5.txt");
my %dates;
while(<INFILE>){
    chomp;
    /(\d+)\.(\d+)\.(\d+)\s+(\d+):(\d+):(\d+)/;
$dates{join(":",($3,$2,$1,$4,$5,$6))}=$_;
}
close
INFILE;
my @sorted_dates=sort %dates;
my $max = $sorted_dates[$#sorted_dates];
my $min = $sorted_dates[0];
my ($ymax,$monmax,$dmax,$hmax,$minmax,$smax)=split(/:/,$max);
my ($ymin,$monmin,$dmin,$hmin,$minmin,$smin)=split(/:/,$min);
$max = s/(\d+):(\d+):(\d+):(\d+):(\d+):(\d+)/$3.$2.$1 $4:$5:$6/;
$min = s/(\d+):(\d+):(\d+):(\d+):(\d+):(\d+)/$3.$2.$1 $4:$5:$6/;
print "Max date: ",$max,"\nMin date: ",$min,"\n";
print "Diff secs:
",((((($ymax-$ymin)*12+($monmax-$monmin))*30+($dmax-$dmin))*24+($hmax-$hmin))*60+($minmax-$minmin))*60+($smax-$smin),"\n";


а результат такой:
Max date:
Min date:
Diff secs:
62166891404
Спасибо сказали:
Sleeping Daemon
Сообщения: 1450

Re: Unix/Shell скрипт

Сообщение Sleeping Daemon »

maroonchik писал(а):
26.09.2008 15:53
Я запускаю, а он не хочет ничего выводить...я правда подстроила под старую версию....что не так то????

Код: Выделить всё

eval
'exec perl -S $0 ${1+"$@"}' if 0;
open(INFILE,"<","5.txt");
my %dates;
while(<INFILE>){
    chomp;
    /(\d+)\.(\d+)\.(\d+)\s+(\d+):(\d+):(\d+)/;
$dates{join(":",($3,$2,$1,$4,$5,$6))}=$_;
}
close
INFILE;
my @sorted_dates=sort %dates;
my $max = $sorted_dates[$#sorted_dates];
my $min = $sorted_dates[0];
my ($ymax,$monmax,$dmax,$hmax,$minmax,$smax)=split(/:/,$max);
my ($ymin,$monmin,$dmin,$hmin,$minmin,$smin)=split(/:/,$min);
$max = s/(\d+):(\d+):(\d+):(\d+):(\d+):(\d+)/$3.$2.$1 $4:$5:$6/;
$min = s/(\d+):(\d+):(\d+):(\d+):(\d+):(\d+)/$3.$2.$1 $4:$5:$6/;
print "Max date: ",$max,"\nMin date: ",$min,"\n";
print "Diff secs:
",((((($ymax-$ymin)*12+($monmax-$monmin))*30+($dmax-$dmin))*24+($hmax-$hmin))*60+($minmax-$minmin))*60+($smax-$smin),"\n";


а результат такой:
Max date:
Min date:
Diff secs:
62166891404

А не проще перевести дату в UNIX_TIME ?
И задача сводится к поиску макс. и мин. числа. И найти разницу в скендах так же просто.
А для вывода перевести найденные даты в исходный вид.
Спасибо сказали:
maroonchik
Сообщения: 6

Re: Unix/Shell скрипт

Сообщение maroonchik »

Заработало!!!!!!
но тока опять не верно.....
max дату вывел верно,но время не максимальное вышло....
с датой и временем у минимальной даты, вообще интересно получается.....выводит время такое, которого в файлах нет, т.е. если смотреть по содержимому файла минимальная дата 6.12.2006 1:16, а мне он выводит 05.06.2006 23:37 - Откуда!!!???
Спасибо сказали:
Аватара пользователя
diesel
Бывший модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian

Re: Unix/Shell скрипт

Сообщение diesel »

maroonchik писал(а):
26.09.2008 16:51
Заработало!!!!!!
но тока опять не верно.....
max дату вывел верно,но время не максимальное вышло....
с датой и временем у минимальной даты, вообще интересно получается.....выводит время такое, которого в файлах нет, т.е. если смотреть по содержимому файла минимальная дата 6.12.2006 1:16, а мне он выводит 05.06.2006 23:37 - Откуда!!!???

можно пример файла который вы загружаете?
Спасибо сказали:
Аватара пользователя
diesel
Бывший модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian

Re: Unix/Shell скрипт

Сообщение diesel »

Sleeping Daemon писал(а):
26.09.2008 16:36
А не проще перевести дату в UNIX_TIME ?
И задача сводится к поиску макс. и мин. числа. И найти разницу в скендах так же просто.
А для вывода перевести найденные даты в исходный вид.

Код: Выделить всё


use strict;
use warnings;
use Time::Local;


my %dates;
while(<>){
    chomp;
    my $time = $_;
    s/(\s+|\.)/:/g;
    my ($mday,$mon,$year,$hour,$min,$sec) = split(/:/);
    $sec = 0 unless defined $sec && $sec;
    $mon--;
    my $unixtime = timelocal($sec,$min,$hour,$mday,$mon,$year);
    $dates{$unixtime} = $time;
}
my @sorted_dates=sort keys %dates;
my $max = $sorted_dates[$#sorted_dates];
my $min = $sorted_dates[0];
print "Max date: ",$dates{$max},"\nMin date: ",$dates{$min},"\n";
print "Difference:",$max-$min,"\n";
Спасибо сказали:
Аватара пользователя
--=Civil696=--
Сообщения: 227
ОС: Gentoo o_O

Re: Unix/Shell скрипт

Сообщение --=Civil696=-- »

а я через /dev/ass сделал, зато с рекурсией :crazy:
формат вводимой даты нужен в виде:

Код: Выделить всё

год месяц число час минуты секунды

поэтому файл вида

Код: Выделить всё

число.месяц.год часы:минуты:секунды

сначало преобразуем вот так:

Код: Выделить всё

cat time.txt | sed 's/[:.]/ /g' | awk '{print $3" "$2" "$1" "$4" "$5" "$6}'

а потом вывод скармливаем ужастному(приведённому ниже) скрипту:

Код: Выделить всё

#!/usr/bin/awk -f

BEGIN {
#выполняется до чтения входных данных
for (i = 0; i <= 6; i++) {
    arrmax[i] = 0 #значения которые точно не встретятся
}

for (i = 0; i <= 6; i++) {
    arrmin[i] = 9999 #значения которые точно не встретятся
}

}


#выполняется во время чтения входных двнных

function max(n, arrmax) { #n - позиция с которой начинаем сравнение
    if ($n > arrmax[n]) {
        for (i = 0; i <= 6; i++) {
            arrmax[i] = $i
        }
        return
    }
    if ($n == arrmax[n]) {
        max(++n, arrmax)
    }
    if ($n < arrmax[n]) {
        return
    }
}

function min(n, arrmin) { #n - позиция с которой начинаем сравнение
    if ($n < arrmin[n]) {
        for (i = 0; i <= 6; i++) {
            arrmin[i] = $i
        }
        return
    }
    if ($n == arrmin[n]) {
        max(++n, arrmin)
    }
    if ($n > arrmin[n]) {
        return
    }
}

{ # анализируем строки
    max(1, arrmax)
    min(1, arrmin)
}

END {

#выполняется после чтения входных данных
print "max: "arrmax[3]":"arrmax[2]":"arrmax[1]" "arrmax[4]"."arrmax[5]"."arrmax[6]
print "min: "arrmin[3]":"arrmin[2]":"arrmin[1]" "arrmin[4]"."arrmin[5]"."arrmin[6]

}

работает :D

Код: Выделить всё

navi ~ $ cat time.txt
01.12.2006 00:00:00
01.12.2007 00:00:00
01.12.2006 00:00:02
02.12.2008 01:00:15
02.11.2008 01:00:11
02.12.2008 01:00:12
01.12.2008 00:00:00
01.10.2008 00:00:21
01.12.2007 00:00:23
navi ~ $ cat time.txt | sed 's/[:.]/ /g' | awk '{print $3" "$2" "$1" "$4" "$5" "$6}' | ./nya.awk
max: 02:12:2008 01.00.15
min: 01:12:2006 00.00.02

вот только как по извращенски разницу в секундах посчитать в голову чёт не пришло :unsure:
НЕ ПАНИКУЙ © ^_~
Спасибо сказали:
maroonchik
Сообщения: 6

Re: Unix/Shell скрипт

Сообщение maroonchik »

интересненько...я даже и не подазревала, что стока вариантов решения этой задачки)всем огромное спасибо!!!
в понедельник, буду пробовать все это реализовать!
надеюсь, с вашей помощью, у меня все получится....наконец то)))

по поводу файла с датами...у меня есть тока фрагмент принт скрина....

вот...
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Спасибо сказали:
Аватара пользователя
--=Civil696=--
Сообщения: 227
ОС: Gentoo o_O

Re: Unix/Shell скрипт

Сообщение --=Civil696=-- »

нлин мну вселенский тормоз, зачем самому писать функцию, если есть sort
всё проще некуда

выводим дату в формате ГГГГ ММ ДД чч мм сс

Код: Выделить всё

cat time.txt | sed 's/[:.]/ /g' | awk '{print $3" "$2" "$1" "$4" "$5" "$6}'
'
а потом тупо сортируем при помощи sort'а

Код: Выделить всё

navi scripts $ cat time.txt | sed 's/[:.]/ /g' | awk '{print $3" "$2" "$1" "$4" "$5" "$6}' | sort
2006 12 01 00 00 00
2006 12 01 00 00 02
2007 12 01 00 00 00
2007 12 01 00 00 23
2008 10 01 00 00 21
2008 11 02 01 00 11
2008 12 01 00 00 00
2008 12 02 01 00 12
2008 12 02 01 00 15

первая строка наименьшая дата, последняя наибольшая
соответственно меньшая дата:

Код: Выделить всё

cat time.txt | sed 's/[:.]/ /g' | awk '{print $3" "$2" "$1" "$4" "$5" "$6}' | sort | head -n 1
2006 12 01 00 00 00
наибольшая дата:

Код: Выделить всё

navi scripts $ cat time.txt | sed 's/[:.]/ /g' | awk '{print $3" "$2" "$1" "$4" "$5" "$6}' | sort -r | head -n 1
2008 12 02 01 00 15
НЕ ПАНИКУЙ © ^_~
Спасибо сказали:
maroonchik
Сообщения: 6

Re: Unix/Shell скрипт

Сообщение maroonchik »

Всем огромное спасибо за помощь, все работает!!!! и главное правильно)))УрАААА
Спасибо сказали:
Sherry
Сообщения: 6

Re: Unix/Shell скрипт

Сообщение Sherry »

И чем все закончилось? Как найти разницу в секундах???
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: Unix/Shell скрипт

Сообщение sash-kan »

Sherry писал(а):
06.06.2012 16:08
Как найти разницу в секундах?
разница вычисляется с помощью операции вычитания·
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
Sherry
Сообщения: 6

Re: Unix/Shell скрипт

Сообщение Sherry »

А поподробней можно?))) например, 2 файла - в каждом по одной дате. как найти разницу?
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: Unix/Shell скрипт

Сообщение sash-kan »

секунды - секунды
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4824
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: Unix/Shell скрипт

Сообщение SLEDopit »

Sherry писал(а):
09.06.2012 15:23
А поподробней можно?))) например, 2 файла - в каждом по одной дате. как найти разницу?
Вы попробуйте тему внимательно прочитать. Тут таки выложили скрипты, которые всё делают. Особое внимание уделите постам diesel'я.
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Unix/Shell скрипт

Сообщение drBatty »

Sherry писал(а):
09.06.2012 15:23
А поподробней можно?))) например, 2 файла - в каждом по одной дате. как найти разницу?

$

(( DIFF = `date +%s --date="now"` - `date +%s --date="last Thursday"` )) $ echo $DIFF 236857


это разница "сейчас" и "прошлый четверг" в секундах.
Подробности man date
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Sherry
Сообщения: 6

Re: Unix/Shell скрипт

Сообщение Sherry »

drBatty писал(а):
09.06.2012 17:47
Sherry писал(а):
09.06.2012 15:23
А поподробней можно?))) например, 2 файла - в каждом по одной дате. как найти разницу?

$

(( DIFF = `date +%s --date="now"` - `date +%s --date="last Thursday"` )) $ echo $DIFF 236857


это разница "сейчас" и "прошлый четверг" в секундах.
Подробности man date

В SunOS это не поможет
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Unix/Shell скрипт

Сообщение drBatty »

Sherry писал(а):
14.06.2012 14:27
В SunOS это не поможет

в Windows95 тоже.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали: