Несколько примеров

Стандартная программа cat читает файлы, чьи имена заданы в командной строке, и выводит на экран содержимое этих файлов. Если в командной строке не указано ни одного имени файла, программа читает данные со стандартного ввода. Напишем программу cat.pl, которая делает то же самое.

Главное применение программы cat — конкатенация нескольких файлов, то есть создание файла, в котором последовательно записано содержимое данных файлов.

Читатели могут задуматься: а для чего может понадобиться программа, читающая со стандартного ввода, и тут же записывающая на стандартный вывод? Ответ: это простой (правда, не очень удобный) способ записать или дописать текст в текстовый файл без помощи текстового редактора:

Если бы мы ориентировались только на вывод текстовых файлов, можно было бы прибегнуть к построчному вводу

#!/usr/bin/perl

use warnings;

push @ARGV, '' unless @ARGV;

for my $fileName(@ARGV)
{
	my $file;
	if($fileName eq '')
	{
		$file=STDIN;
	}
	else
	{
		unless(open $file, '<', $fileName)
		{
			warn "Невозможно открыть файл «$fileName»: $!\n";
			next;
		}
	}
	print while <$file>;
	close $file or warn "Невозможно закрыть файл «$fileName»: $!\n";
}

Если массив @ARGV пуст, добавляем в него пустое имя файла. В цикле, перебирающем имена файлов, пустые имена обрабатываются особым образом. Вместо открытия дескриптора переменной $file присваивается значение стандартного дескриптора, уже открытого для ввода.

Команда print while <$file> является рискованной. Если наша программа используется для нетекстовых файлов, считываемые строки могут оказаться огромными, если символы конца строки встречаются редко. Это может вызвать острую нехватку памяти со всеми вытекающими неприятными последствиями. Безопасный подход состоит в применении посимвольного ввода. Нужно заменить эту команду на print while read $file, $_, 4096, тогда данные будут считываться порциями по 4096 символов:

#!/usr/bin/perl

use warnings;

push @ARGV, '' unless @ARGV;

for my $fileName(@ARGV)
{
	my $file;
	if($fileName eq '')
	{
		$file=STDIN;
	}
	else
	{
		unless(open $file, '<', $fileName)
		{
			warn "Невозможно открыть файл «$fileName»: $!\n";
			next;
		}
	}
	print while read $file, $_, 4096;
	close $file or warn "Невозможно закрыть файл «$fileName»: $!\n";
}

Стандартная утилита uniq считывает со стандартного ввода строки и выводит их, заменяя несколько подряд идущих одинаковых строк на единственный экземпляр. Утилита может использоваться для устранения повторов и вывода списка уникальных значений. Если одинаковые строки встречаются не подряд можно использовать uniq в связке с утилитой sort, сортирующей строки в лексикографическом порядке. Например, для файла names.txt

Сергей
Ольга
Антон
Степан
Алексей
Алексей
Ольга
Светлана
Сергей

следующая команда выдаст упорядоченный по алфавиту список имён без повторов:

% cat names.txt |sort |uniq Алексей Антон Ольга Светлана Сергей Степан

Программа uniq умеет также (при соответствующих опциях в командной строке) подсчитывать количество повторов и читать данные не только со стандартного ввода, но и из файлов. Мы реализуем упрощённый вариант утилиты (без этих дополнительных возможностей) — программу uniq.pl.

#!/usr/bin/perl

use warnings;

my $prev;

while(<STDIN>)
{
	print if not defined $prev or $_ ne $prev;
	$prev=$_;
}
Информатика-54© А. Н. Швец