Прочитайте и напишите текстовый файл - PullRequest
0 голосов
/ 25 августа 2011

Как прочитать и написать текстовый файл и поместить его в тот же файл? Я пытался, но получил пустые файлы.

Мой код:

#!/opt/lampp/bin/perl    
print "Content-Type : text/html\n\n";    
$ref = '/opt/lampp/htdocs/perl/Filehandling/data_1.txt';    
open(REF, "+<", $ref) or die "Uable to open the file $ref: $!";    
while (<REF>) {    
    if($_=~ m/Others/gi) {
        $_  =~ s/Others/Other/gi;
        print "$_\n";
    }
}

$ref = '/opt/lampp/htdocs/perl/Filehandling/data_1.txt';

open(REF, "+>", $ref) or die "Uable to open the file $ref: $!";
print REF "$_\n";
close REF;
close REF;

Ответы [ 3 ]

4 голосов
/ 25 августа 2011
perl -pi -e 's/Others/Other/gi' /opt/lampp/htdocs/perl/Filehandling/data_1.txt

Опция -i редактирует файл на месте, т.е. перезаписывает файл новым содержимым.

Оператор s/// ничего не подставляет, если не найдено совпадений, поэтому вам не нужно проверять с помощью m// совпадение, прежде чем пытаться выполнить замену.

Контроль потока в вашем скрипте некорректен; вы открываете для чтения, затем выводите на стандартный вывод (не обратно в файл), затем открываете для записи, но не пишите ничего полезного (или, ну, только последнюю строку, которую вы прочитали в цикле ввода).

Что с заголовком Content-Type:, вы хотите запустить его как скрипт CGI? Это звучит как проблема безопасности.

Вы хотите печатать, только если есть замена? Если это так, попробуйте это:

perl -ni -e 's/Others/Other/ig and print' /opt/lampp/htdocs/perl/Filehandling/data_1.txt

Обратите внимание на изменение с -p, которое добавляет цикл чтения и печати вокруг вашего скрипта, на -n, который только читает, но не печатает ваш файл.

2 голосов
/ 25 августа 2011

Fᴍᴛᴇʏᴇᴡᴛᴋ: Learning How to Learn Как обновить текстовый файл на месте

Если бы вы только Rᴇᴄᴏɴɴᴏɪᴛʀᴇ Tʜᴇ Fᴀʙᴜʟᴏᴜs perlfaq5 Mᴀɴᴘᴀɢᴇ - который доступен для каждой установки Perl по всему миру, включая вашу собственную - вы легко узнаете ответ на свой вопрос под этим Fᴏʀᴍɪᴅᴀʙʟʏ Aᴘᴏᴛʜᴇᴏsɪᴢᴇᴅ Qᴜᴀɴᴅᴀʀʏ под названием « Как изменить, удалить или вставить строкув файле, или добавить в начало файла? ».

Каким-то образом этот ключевой первый шаг к решению проблемы не был выполнен.

Обучение эффективному поиску стандартного набора документации Perl - это один из трех ключевых шагов в становлении опытным программистом Perl.(Для записи, два других должны иметь rolodex, полный рабочих примеров и иметь определенный зуд, который вам нужно поцарапать, и вы можете использовать Perl, чтобы поцарапать его.)

Если вы по какой-либо причине вы либоне может или не будет искать стандартную документацию, и, таким образом, вы окажетесь в Интернете, прося помощи в выполнении того, о чем давно уже было сказано в этом наборе документации, вы никогда не будете самостоятельно активированы.Вы также можете восприниматься как вредитель.


Рецепт Rolodex ?

Выход за рамки стандартной документации, прилагаемой к каждой установке Perl , содержимое которой вы должны были искать раньшеПриходя сюда, , мы обнаруживаем, что глава 7 Perl Cookbook О'Рейли *1027* «Доступ к файлам» и глава 8 «Содержимое файла» содержат несколько рецептов, особенно относящихся к вашему текущему вопросу, особенно, но не тольковыделено жирным шрифтом ниже. Поваренная книга Perl представляет собой сборник примеров кода, обозначаемый как парный сопутствующий том до Programming Perl .Возможно, поваренная книга еще более полезна для начинающего программиста на Perl, чем сам Camel.

Однако вы не можете бросать мертвые деревья.Поэтому я покажу вам, что вы должны искать и как это делать, независимо от того, обладаете ли вы неимоверной версией мертвого дерева этого конкретного праймера или нет.

NB: Хотя я уверен, чточто издатель будет рад, если вы купите этот важный Perl-файл, будь то мертвое дерево или в электронном виде, я признаю, что это возможно не для всех, поэтому ниже я покажу вам, как получить доступ к соответствующим частям совершенно бесплатно.,На самом деле, я включил их для вашего удобства.

Во-первых, оглавление главы 7 Perl Cookbook :

  • Рецепт 7.0: Введение в доступ к файлам
  • Рецепт 7.1: Открытие файла
  • Рецепт 7.2: Открытие файлов с необычными именами файлов
  • Рецепт 7.3: Расширение тильд в именах файлов
  • Рецепт 7.4: Создание имен файлов отчетов Perl в сообщениях об ошибках
  • Рецепт 7.5: Сохранение файловых дескрипторов в переменные
  • Рецепт 7.6: Написание подпрограммы, которая принимает файловые дескрипторы как встроенные функции, Делать
  • Рецепт7.7: Кэширование открытых выходных файловых дескрипторов
  • Рецепт 7.8: Одновременная печать на нескольких файловых дескрипторах
  • Рецепт 7.9: Открытие и закрытие файловых дескрипторов по номеру
  • Рецепт 7.10: Копирование файловых дескрипторов
  • Рецепт 7.11: Создание временных файлов
  • Рецепт 7.12: Хранение файла внутри текста вашей программы
  • Рецепт 7.13: Хранение нескольких файлов в области DATA
  • Рецепт 7.14: Написание программы фильтра в стиле Unix
  • ☞ Рецепт 7.15: Изменение файла с помощью временного файла
  • ☞ Рецепт 7.16: Изменениефайл на месте с помощью -i Переключатель
  • ☞ Рецепт 7.17: Изменение файла на месте без временного файла
  • Рецепт 7.18: Блокировка файла
  • Рецепт 7.19: очистка вывода
  • Рецепт 7.20: Выполнение неблокирующего ввода / вывода
  • Рецепт 7.21: Определение количества непрочитанных байтов
  • Рецепт 7.22:Чтение из Млюбые файловые дескрипторы без блокировки
  • Рецепт 7.23: чтение всей строки без блокировки
  • Рецепт 7.24: Программа: netlock
  • Рецепт 7.25: Программа: lockarea

А вот глава 8:

  • ☞ Рецепт 8.0: Введение в содержимое файла
  • Рецепт 8.1. Чтение строк с символами продолжения
  • Рецепт 8.2. Подсчет строк (или абзацев или записей) в файле
  • Рецепт 8.3: Обработка каждого слова в файле
  • ☞ Рецепт 8.4: чтение файла в обратном порядке по строке или абзацу
  • Рецепт 8.5: Слежение за растущим файлом
  • Рецепт 8.6: Выбор случайной строки из файла
  • Рецепт 8.7: Рандомизация всех строк
  • ☞ Рецепт 8.8: Чтение отдельной строки в файле
  • Рецепт 8.9: Обработка текстовых полей переменной длины
  • ☞ Рецепт 8.10: Удаление последней строки файла
  • Рецепт 8.11: обработка двоичных файлов
  • Рецепт 8.12: Использование ввода-вывода с произвольным доступом
  • ☞ Рецепт 8.13: Обновление файла с произвольным доступом
  • Рецепт 8.14: чтение строки из двоичного файла
  • Рецепт 8.15: Чтение записей фиксированной длины
  • Рецепт 8.16: Чтение файлов конфигурации
  • Рецепт 8.17: Тестирование файладля надежности
  • Рецепт 8.18: Обработка файла как массива
  • Рецепт 8.19: Установка слоев ввода / вывода по умолчанию
  • Рецепт 8.20: Чтение илиЗапись Unicode из файлового дескриптора
  • Рецепт 8.21: Преобразование собственных текстовых файлов Microsoft ® в стандартный Unicode
  • Рецепт 8.22: Сравнение содержимого двух файлов
  • Рецепт 8.23: представление строки в файле
  • Рецепт 8.24: Программа: tailwtmp
  • Рецепт 8.25: Программа: tctee
  • Рецепт 8.26: Программа: laston
  • Рецепт 8.27: Программа:Индексы плоских файлов

Muddled Mental Models ?

Раздел 8.0 «Введение в содержимое файла» главы 8 особенно острый, настолько, что его авторский текст, который я здесь воспроизводю с помощьюЛюбезное разрешение автора:

Обработка файлов как неструктурированных потоков обязательно определяет, что вы можете с ними делать.Вы можете читать и записывать последовательные блоки данных фиксированного размера в любом месте файла, увеличивая его размер, если вы пишете после текущего конца.Perl использует библиотеку ввода-вывода, которая эмулирует C stdio (3) для реализации чтения и записи записей переменной длины, таких как строки, абзацы и слова.

Что вы не можете сделатьв неструктурированный файл?Поскольку вы не можете вставлять или удалять байты где-либо, кроме конца файла, вы не можете легко изменять длину, вставлять или удалять записи.Исключением является последняя запись, которую можно удалить, обрезав файл до конца предыдущей записи.Для других модификаций вам нужно использовать временный файл или работать с копией файла в памяти.Если вам нужно сделать это много, система баз данных может быть лучшим решением, чем необработанный файл.Стандарт с Perl начиная с v5.8 - это модуль Tie::File, который предлагает интерфейс массива для файлов записей.

Последняя ссылка может быть наиболее полезной,потому что он предлагает модель текстового файла, которая может лучше соответствовать представлению непрограммиста о том, что такое текстовый файл. Для операционной системы файл - это просто упорядоченный набор байтов, и единственными операциями, которые вы можете использовать над файлом, являются чтение, запись, поиск и усечение. Он есть на вставке, здесь нет номера строки N и, конечно, нет поиска и замены. Модель операционной системы больше похожа на устройство чтения бумажных лент, чем на колоду карт. Вы не можете больше вставлять новые данные в середину файла, чем вставлять новый сектор между существующими на жестком диске. Знаете, они не зовут это жесткий диск.

Проблема в том, что непрограммист не имеет опыта работы с моделью операционной системы для фиксированного файла, заполненного байтами. Ее единственная модель для текстового файла - это модель, операции которой совпадают с операциями текстового редактора, к которому она привыкла, и которая в эти дни до Интернета [ sic ] вычислений часто больше напоминает детскую видеоигру чем серьезный инструмент для выполнения реальной работы.

Независимо от того, есть ли у вас версия видеоигры или версия с мощным инструментом, все текстовые редакторы почти всегда основаны на строках и позволяют перемещать строки, выполнять поиск по строкам, изменять строки, включая их длину, вставлять в середину файл или удалить из середины, сокращая все вверх. Даже ее представление о символе сильно отличается от операционной системы, поскольку видимая пользователем графема может легко содержать несколько видимых программисту кодовых точек, и каждая из этих кодовых точек может легко содержать несколько видимых операционной системой кодовых блоков.

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


ᴘʟᴇᴀᴄ: Примеры языков программирования Alike Cookbook

Вы когда-нибудь хотели Rosetta Stone для языков программирования? Если так, то сегодня твой счастливый день. ?

Хотя опубликованный полный код Perl Cookbook доступен для бесплатной и простой загрузки , вы также можете найти интересный проект , многоязычный Примеры языков программирования Alike Cookbook . Он включает в себя не только полный код Perl Cookbook , но также переводы в различных состояниях полноты на другие популярные языки программирования, такие как Ruby и Python, старые языки, такие как Rexx и TCL, зарождающиеся языки, такие как Go и Groovy, и экзотические такие языки, как Haskell и OCaml (никакого отношения к ?:).

Я цитирую ниже из источника проекта for три соответствующих рецепта из Perl Cookbook .


Рецепт 7.15: изменение файла с временным файлом

# ^^PLEAC^^_7.8
#-----------------------------
open(OLD, "< $old")         or die "can't open $old: $!";
open(NEW, "> $new")         or die "can't open $new: $!";
while (<OLD>) {
    # change $_, then...
    print NEW $_            or die "can't write $new: $!";
}
close(OLD)                  or die "can't close $old: $!";
close(NEW)                  or die "can't close $new: $!";
rename($old, "$old.orig")   or die "can't rename $old to $old.orig: $!";
rename($new, $old)          or die "can't rename $new to $old: $!";
#-----------------------------
while (<OLD>) {
    if ($. == 20) {
        print NEW "Extra line 1\n";
        print NEW "Extra line 2\n";
    }
    print NEW $_;
}
#-----------------------------
while (<OLD>) {
    next if 20 .. 30;
    print NEW $_;
}
#-----------------------------

Рецепт 7.16: изменение файла на месте с помощью переключателя -i

# ^^PLEAC^^_7.9
#-----------------------------
#% perl -i.orig -p -e 'FILTER COMMAND' file1 file2 file3 ...
#-----------------------------
#!/usr/bin/perl -i.orig -p
# filter commands go here
#-----------------------------
#% perl -pi.orig -e 's/DATE/localtime/e'
#-----------------------------
while (<>) {
    if ($ARGV ne $oldargv) {           # are we at the next file?
        rename($ARGV, $ARGV . '.orig');
        open(ARGVOUT, ">$ARGV");       # plus error check
        select(ARGVOUT);
        $oldargv = $ARGV;
    }
    s/DATE/localtime/e;
}
continue{
    print;
}
select (STDOUT);                      # restore default output
#-----------------------------
#Dear Sir/Madam/Ravenous Beast,
#    As of DATE, our records show your account
#is overdue.  Please settle by the end of the month.
#Yours in cheerful usury,
#    --A. Moneylender
#-----------------------------
#Dear Sir/Madam/Ravenous Beast,
#    As of Sat Apr 25 12:28:33 1998, our records show your account
#is overdue.  Please settle by the end of the month.
#Yours in cheerful usury,
#    --A. Moneylender
#-----------------------------
#% perl -i.old -pe 's{\bhisvar\b}{hervar}g' *.[Cchy]
#-----------------------------
# set up to iterate over the *.c files in the current directory,
# editing in place and saving the old file with a .orig extension
local $^I   = '.orig';              # emulate  -i.orig
local @ARGV = glob("*.c");          # initialize list of files
while (<>) {
    if ($. == 1) {
        print "This line should appear at the top of each file\n";
    }
    s/\b(p)earl\b/${1}erl/ig;       # Correct typos, preserving case
    print;
} continue {close ARGV if eof} 
#-----------------------------

Рецепт 7.17: изменение файла на месте без временного файла

# ^^PLEAC^^_7.10
#-----------------------------
open(FH, "+< FILE")                 or die "Opening: $!";
@ARRAY = <FH>;
# change ARRAY here
seek(FH,0,0)                        or die "Seeking: $!";
print FH @ARRAY                     or die "Printing: $!";
truncate(FH,tell(FH))               or die "Truncating: $!";
close(FH)                           or die "Closing: $!";
#-----------------------------
open(F, "+< $infile")       or die "can't read $infile: $!";
$out = '';
while (<F>) {
    s/DATE/localtime/eg;
    $out .= $_;
}
seek(F, 0, 0)               or die "can't seek to start of $infile: $!";
print F $out                or die "can't print to $infile: $!";
truncate(F, tell(F))        or die "can't truncate $infile: $!";
close(F)                    or die "can't close $infile: $!";
#----------------------------

Заключение

Там. Если это не указывает на способ ответить на ваш вопрос, я не знаю, что будет. Но держу пари, что так и было. Congrats! ?

2 голосов
/ 25 августа 2011

Кажется, что вам нужно только s/Others/Other/gi в вашем data_1.txt. Вы можете сделать это намного проще с помощью одной строки: perl -pi.bak -e's/Others/Other/gi' data_1.txt.

Если вы все еще хотите читать и записывать в один и тот же файл, вы можете проверить модуль IO :: InSitu на CPAN.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...