2015-02-28 5 views
1

Я предполагал, что print "foo" является просто ярлыком для print STDOUT "foo".Какова цель печати `perl` по умолчанию?

Однако я не заметил, что (по крайней мере) в сочетании с переключателем -i это предположение уже не имеет:

perl -ni 'print $_' file 

это просто не изменяет содержимое файла.

perl -ni 'print STDOUT $_' file 

Это, однако, печатает содержимое терминала и оставляет файл пустым.

Поэтому вопрос: какова цель печати по умолчанию? То есть где печатает первую печать?

perldoc -f print говорит:

Для установки вывода по умолчанию дескриптор в нечто иное, чем STDOUT, используйте операции выбора.

Очевидно, что perl внутренне использовал операцию select, чтобы установить дескриптор вывода по умолчанию на что-то еще. Есть ли способ явно указать текущий дескриптор вывода по умолчанию?

Это позволило бы мне написать что-то вроде

perl -i -wne 'print {/b/ ? STDOUT : XXX } $_' file 

построить grep, который удаляет все печатные линии.

+0

Вы посмотрели документы для флага '-i'? Что ты изучал? – Mat

+0

Да, я сначала искал опцию '-i' в' man perlrun'. Я не мог найти ответ. – michas

ответ

4

Рукоятка файла по умолчанию для print управляется функцией select. По умолчанию он равен STDOUT, но может быть изменен в любое время.

Цитирую the documentation:

  • выберите FILEHANDLE
  • выберите

    Возвращает выбранный дескриптор. Если FILEHANDLE поставляется, устанавливает новый текущий дескриптор файла по умолчанию для вывода. У этого есть два эффекта: во-первых, write или print без дескриптора файла по умолчанию этот FILEHANDLE. Во-вторых, ссылки на переменные, связанные с выходом , относятся к этому выходному каналу.

Если вы посмотрите на documentation for the -i option, вы увидите, что расширение включает в себя линию select(ARGVOUT). Именно это приводит к возврату вывода к редактируемому файлу.

ARGVOUT является особенным только во время -i обработки, но он работает там:

$ cat foo 
a1 
b1 
a2 
b2 
$ perl -i -wne 'print {/b/ ? STDOUT : ARGVOUT } $_' foo 
b1 
b2 
$ cat foo 
a1 
a2 

Вы также можете использовать perl -i -wne 'print {/b/ ? STDOUT : select } $_' foo так ARGVOUT будет выбран в данный момент указатель_на_файл.

+0

ARGVOUT является специальным только при выполнении кода под '-i'. Извините, если вы решили, что я подразумеваю иначе. – cjm

+0

Используйте 'select' без аргумента, чтобы получить текущий выбранный дескриптор файла. – cjm

+0

Упс, убежден. Они работают. Благодарю. – michas

0

Он печатает выбранный в данный момент дескриптор, который по умолчанию равен STDOUT. Вы можете изменить выбранный дескриптор самостоятельно, используя форму с одним аргументом select, а режим редактирования в месте -i flag/$^I автоматически выбирает файл назначения для вас (см. Описание -i в perlrun для кода, эквивалентного тому, что делает -i).