Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Системное программирование > Удаление строк из файла


Автор: Klif 2.3.2004, 18:09
Помогите плз, у меня затык!

Ситуация такая- есть текстовый файл со статистикой. Но в начале файла есть ненужная инфа о времени и т.д. - 4 строчки.
Как мне их удалить?

или может как обойти эти строчки ?
вот мой cкрипт:

while (<File>){
tr/ / /s;
($stat1,$stat2,$stat3,stat4) = split(/ /,$_);

$result=$result+$stat3;

}
print $result;

Автор: korob2001 2.3.2004, 18:31
Способов как обычно несколько.
1. Воспользуйся следующей конструкцией next if /shablon/;
Например если в каждой из этих четырёх строк есть время в следующем формате 15:34:20, то шаблон будет примерно таким:
next if /\d{1,2}:\d{2}:\d{2}/;

2. Можно также создать переменную, счётчик:
Например:
Код

my $num_of_string = 0; # Переменная счётчик
while (<File>){
$num_of_string++;    # Инкрементируем переменную счётчик
next if $num_of_string < 4; #Пропускаем первые 4 строки
tr/ / /s;
($stat1,$stat2,$stat3,stat4) = split(/ /,$_);

$result=$result+$stat3;

}

Удачи ;)

Автор: GoodBoy 3.3.2004, 11:20
а можно и вот так:
Код

open(File, "file.stat");  # откроем файл
@lines = <File>;          # прочитаем его
close(File);              # закроем
chomp @lines;             # отрежем символы \n в конце каждой строки
splice(@lines, 0, 4);     # удалим из масива строк 4 строки, начиная с 0-й позиции
foreach (@lines) {        # для каждой строки...
   tr/ / /s;
   ($stat1,$stat2,$stat3,stat4) = split(/ /,$_);
   $result=$result+$stat3;
}
print $result;

smile.gif

Автор: Unregistered 3.3.2004, 13:18
Спасибо большое!
Все работает!
Спасли мою грешую голову smile.gif))

Автор: ElectricalStorm 3.3.2004, 22:20
Цитата

@lines = <File>; 

не клева так делать

лучше как korob2001 написал быстрее будет
Код

while (<FILE>) {
   next if 1..4; # пропускаем строки
  #  ($stat1,$stat2,$stat3,stat4) = split;  по умолчанию тут все если не все
       переменные используются то лучше поставить undef
   (undef, undef, $stat3, undef)  = split; # или ваще (split)[2]
   $result += $stat3;
}


преобразуется

Код

while (<File>) {
   next if 1..4;
   $res += (split)[2];
}
print $res;







Автор: korob2001 3.3.2004, 22:31
Как написал ElectricalStorm.

Попробуй заменить строку:

$result=$result+$stat3;

такой строкой

$result += $stat3;

Второй вариант делает те же действия, только быстрее.

Почему?

Потому что, значение переменной $result вычисляется только 1 раз, а в твоем варианте 2 раза.

Но в принципе твой вариант тоже прекрасно работает. Как тебе удобней так и пиши, я только посоветовал. ;)

Удачи.

Автор: Klif 4.3.2004, 11:07
To korob2001

Принял к сведенью. Спасибо за совет.Я просто не думал над оптимизацией когда писал. Я просто не так давно начал кодить... теперь буду повнимательнее над кодом... smile.gif

Автор: Гость_case 4.3.2004, 13:15
оптимально так

1. cменить признак конца строки
2. считать весь файл в одну переменную
3. заменить =~ /(.+\n){4}//gi
4. записать переменную в файл

Автор: korob2001 4.3.2004, 19:46
Цитата
2. считать весь файл в одну переменную

При условии, что файл не будет слишком большим.

Автор: Klif 5.3.2004, 10:59
Я поначалу так и сделал ... но так как файлы у меня могут быть мегабайт по 20... и обращений по 5-10 одновременно ... и все это с перспективой роста !


Вобщем боюсь нету у меня денег на такой сервер smile.gif

GoodBoy дал действительно более действенный вариант !
У меня скрипт стал раза в 3 меньше smile.gif

Автор: ElectricalStorm 5.3.2004, 16:06
зато в 3 раза тормознее smile.gif

Автор: korob2001 5.3.2004, 18:44
Цитата
У меня скрипт стал раза в 3 меньше

Опртимизировать код, это не значит уменьшить кол-во строк.
При оптимизации в первую очередь необходимо учитывать расход ресурсов, а только потом уменьшение размера кода.

Такой вариант:
Код

open( FILE, "< myfile.txt" ) or die "Can't open file 'myfile.txt': $!";
 my @all_file = <FILE>;
close( FILE ) or die "Can't close file 'myfile.txt': $!";

подходит только в том случае, если файл будет не слишком большим. Дело в том, что в этом случае сразу содержимое всего файла присваивается массиву @all_file, в котором каждый элемент будет содержать по одной строке. Другими словами, мы записали весь файл в оперативную память. Прошу обратить внимание на то, что оперативная память, конечна, как и всё остальное в этой жизни. ;)

А что касается такого варианта:
Код

open( FILE, "< myfile.txt" ) or die "Can't open file 'myfile.txt': $!";
while( <FILE> ) {
   # Обрабатываем каждую строку по очереди
}
close( FILE ) or die "Can't close file 'myfile.txt': $!";

то, у нас получается такая вот бодяга:

1. Мы открываем файл.
2. Читаем файл построчно, при этом каждая строка присваивается переменной $_. Если такая переменная не устраивает, то можно воспользоваться конструкцией while( my $line = <FILE> ) { блок кода };
3. Закрываем файл.

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

Удачи.

Автор: GoodBoy 5.3.2004, 18:55
korob2001 Согласен. При написании своего варианта я и имел в виде небольшие файла, ибо Klif не сказал изначально о 20 Мб с перспективой роста... :-))))))) Для небольших же файлов это вполне оправдано!

Автор: korob2001 5.3.2004, 19:05
Цитата
Для небольших же файлов это вполне оправдано!

Согласен.
Тем более оперировать массивом гораздо проще, чем файлом. Но при этом, для себя сразу нужно решить, что файл не будет большим.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)