Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вопросы по работе с файлами, Работа с текстовыми файлами 
V
    Опции темы
d0k
  Дата 19.3.2006, 18:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 27.5.2005

Репутация: нет
Всего: нет



Тема такова:
Открываем файл , считываем строки <filehandle>. Необходимо изменять положение текущей считываемой строки ( также положение текущей записи в файл). Переменная $. изменяется по порядку как и должна показывает номер строки. $/ не трогаю (по умолчанию). Но если я меняю $. , надеясь перейти на определенную строку, то просто $. изменяется, а указатель остаётся на том же месте и аккумулируется уже от мною заданного значения. Почему?
И всё-таки как изменить указатель строки?

Для понимания более точный вопрос :
Как перейти на последнию строку или как считать строку с заданным номером? smile

seek и tell - работают с байтами - это понятно, а нет ли чего похожего но для работы со строками? smile
PM MAIL   Вверх
BlackLFL
Дата 19.3.2006, 18:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 8
Всего: 12



Цитата(d0k @ 19.3.2006, 19:35 Найти цитируемый пост)
seek и tell - работают с байтами - это понятно, а нет ли чего похожего но для работы со строками?

perldoc read
Цитата

    read FILEHANDLE,SCALAR,LENGTH,OFFSET
    read FILEHANDLE,SCALAR,LENGTH
            Attempts to read LENGTH *characters* of data into variable
            SCALAR from the specified FILEHANDLE. Returns the number of
            characters actually read, 0 at end of file, or undef if there
            was an error (in the latter case $! is also set). SCALAR will be
            grown or shrunk so that the last character actually read is the
            last character of the scalar after the read.

            An OFFSET may be specified to place the read data at some place
            in the string other than the beginning. A negative OFFSET
            specifies placement at that many characters counting backwards
            from the end of the string. A positive OFFSET greater than the
            length of SCALAR results in the string being padded to the
            required size with "\0" bytes before the result of the read is
            appended.

            The call is actually implemented in terms of either Perl's or
            system's fread() call. To get a true read(2) system call, see
            "sysread".

            Note the *characters*: depending on the status of the
            filehandle, either (8-bit) bytes or characters are read. By
            default all filehandles operate on bytes, but for example if the
            filehandle has been opened with the ":utf8" I/O layer (see
            "open", and the "open" pragma, open), the I/O will operate on
            UTF-8 encoded Unicode characters, not bytes. Similarly for the
            ":encoding" pragma: in that case pretty much any characters can
            be read.

PM WWW   Вверх
nitr
Дата 19.3.2006, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2543
Регистрация: 10.2.2006
Где: Россия :)

Репутация: 37
Всего: 84



если файлик маленький:

можно через массив
@content = <HANDLE>;
искомая строка $str = $content[NUMBER-1]; , начиная с 1 smile, если хоцца с нуля то просто [NUMBER]

Вот хорошее решение для любого размера и большая скорость -
читать тут
Он занимаеться тем же smile Представляет файлик как массив smile
Код

use Tie::File;
use Fcntl;

tie @content, 'Tie::File', $file, mode => O_RDWR or die "Error - $!\n";
print "$content[NUMBER-1]\n";

и последняя строка: print "$content[-1]\n";

Для чего тебе это всё? Покажи кусок кода smile Вариантов немеренно. даже можно работать с файлом как БД =)

Вот по твоему вопросу:
Код

#!/usr/bin/perl -w
# ex.pl

$file = "ex.pl";
open HANDLE, "< $file";
while(<HANDLE>) {
  #что-то делаем
  last if $. == 4;
}
print;

результат $file = "ex.pl";

для последней:
Код

#!/usr/bin/perl -w
# ex.pl

$file = "ex.pl";
open HANDLE, "< $file";
while(<HANDLE>) {
  #что-то делаем
  last if eof;
}
print;

результат print;

Это сообщение отредактировал(а) nitr - 19.3.2006, 19:50


--------------------
PM   Вверх
BlackLFL
Дата 19.3.2006, 18:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 8
Всего: 12



Цитата

Для чего тебе это всё? Покажи кусок кода  Вариантов немеренно. даже можно работать с файлом как БД =)

поддерживаю
PM WWW   Вверх
d0k
Дата 19.3.2006, 20:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 27.5.2005

Репутация: нет
Всего: нет



Мне это нужно, чтобы просто к любому символу в любой строке текстового файла можно было обратиться.
Ещё поясню, прочитал (в perldoc),что изменяя переменную $. (в которой хранится номер текущей строки) можно обращаться к любой строке:
Код

open (FILEIO,"+>file");
while ($a=<FILEIO>){
print "$a   $."; # $. изменяется по порядку
}
$.=5;
$a=<FILEIO>;
print $a; #печатает пятую строку


Массив подходит - но не целесообразно после изменений в одной строке сохранять весь массив, особенно если он на 100000 строк.
Массив можно, но как тогда заменить в файле именно определённую строку,а не переписывать весь массив в файл заного.

nitr написал:
Код

file = "ex.pl";
open HANDLE, "< $file";
while(<HANDLE>) {
  #что-то делаем
  last if eof;
}
print;

Это верно - когда мы просто перебором доходим до последней строки, а дальше как вернуться вверх? Или начать перебор заного? А если в файле 100000 строк.
А как после того как мы прочитали последнию строку прочитать предпоследнию а затем 4-ую затем 8-ую 2-ую и т.д. в любой последовательности?

PM MAIL   Вверх
nitr
Дата 19.3.2006, 21:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2543
Регистрация: 10.2.2006
Где: Россия :)

Репутация: 37
Всего: 84



Цитата

если файлик маленький:

можно через массив
@content = <HANDLE>;
искомая строка $str = $content[NUMBER-1]; , начиная с 1 smile, если хоцца с нуля то просто [NUMBER]

Вот хорошее решение для любого размера и большая скорость -
читать тут
Он занимаеться тем же smile Представляет файлик как массив smile
Код

use Tie::File;
use Fcntl;

tie @content, 'Tie::File', $file, mode => O_RDWR or die "Error - $!\n";
print "$content[NUMBER-1]\n";

и последняя строка: print "$content[-1]\n";


читать тут ВНИМАТЕЛЬНО и для чего это smile Пользуйся им. Можно ещё и как с БД smile
Код

use DB_File;
use Fcntl;
$tie = tie(@content, DB_File, $file, O_RDWR, 0755, $DB_RECNO);
print $content[NUMBER-1];


Это сообщение отредактировал(а) nitr - 19.3.2006, 21:06


--------------------
PM   Вверх
nitr
Дата 19.3.2006, 21:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2543
Регистрация: 10.2.2006
Где: Россия :)

Репутация: 37
Всего: 84



один из самых простых подсчётов строк
Код

open HANDLE, "< $file";
for($lines=0; <HANDLE>; $lines++) {}



--------------------
PM   Вверх
d0k
Дата 23.3.2006, 02:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 27.5.2005

Репутация: нет
Всего: нет



smile nitr спасибо
DB_File очень удобная библиотека в прямом смысле привязал хеш к файлу и никаких проблем. Berkeley DB рулят, но уж слишком заумно сделано.

ладно разберусь
PM MAIL   Вверх
Бонифаций
Дата 23.3.2006, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 827
Регистрация: 15.9.2005
Где: Brisbane

Репутация: нет
Всего: 40



Цитата(d0k @ 19.3.2006, 20:53 Найти цитируемый пост)
Массив подходит - но не целесообразно после изменений в одной строке сохранять весь массив, особенно если он на 100000 строк.
Массив можно, но как тогда заменить в файле именно определённую строку,а не переписывать весь массив в файл заного.



Очень интересно. А как вы собираетесь изменить только одну строку в тестовом файле?. Вы полагаете текстовые редакторы не переписывают файлы если вы изменили только одну строку?


--------------------
 Бонифаций.
 
PM MAIL ICQ Skype GTalk Jabber YIM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1199 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.