Чтение файла по строкам или абзацам в обратном направлении

Проблема

Требуется обработать каждую строку или абзац файла в обратном направлении.

Решение

Прочитайте все строки в массив и организуйте обработку элементов массива от конца к началу:
@lines = <FILE>;
while ($line = pop @lines) {
  # Сделать что-то с $line
}
Или занесите строки в массив в обратном порядке:
@lines = reverse <FILE>;
foreach $line (@lines) {
  # Сделать что-то с $line
}

Комментарий

Ограничения, связанные с доступом к файлам, не позволяют последовательно читать строки с конца файла. Приходится читать строки в память и обрабатывать их в обратном порядке. Конечно, расходы памяти при этом будут по крайней мере не меньше размера файла.
В первом варианте массив строк перебирается в обратном порядке. Такая обработка является деструктивной, поскольку при каждой итерации из массива выталкивается последний элемент. Впрочем, то же самое можно сделать и недеструктивно:
for ($i = $#lines; $i != -1; $1--) {
  $line = $lines[$i];
}
Во втором варианте генерируется массив строк, изначально расположенных в обратном порядке. Его тоже можно обработать недеструктивно. Мы получаем массив с обратным порядком строк, поскольку присваивание @lines обеспечивает вызов reverse в списковом контексте, что, в свою очередь, обеспечивает списковый контекст для оператора <FILE>. В списковом контексте <> возвращает список всех строк файла.
Показанные решения легко распространяются на чтение абзацев, достаточно изменить значение $/:
# Внешний блок обеспечивает существование временной локальной копии $/
{
local $/ = '' ;
@paragraphs = reverse <FILE>;
}
foreach $paragraph (@paragraphs) {
  # Сделать что-то
}

См. также

Описание функции reverse



2013-09-10 17:05:19

Proverte kod v komentariyah gde pro list tam oshibki detskie




Оставить комментарий:
Ваше Имя:
Email:
Антибот: *  
Ваш комментарий: