InglesPransesEspanyol

OnWorks favicon

perlfaq5 - Online sa Cloud

Patakbuhin ang perlfaq5 sa OnWorks na libreng hosting provider sa Ubuntu Online, Fedora Online, Windows online emulator o MAC OS online emulator

Ito ang command na perlfaq5 na maaaring patakbuhin sa OnWorks na libreng hosting provider gamit ang isa sa aming maramihang libreng online na workstation gaya ng Ubuntu Online, Fedora Online, Windows online emulator o MAC OS online emulator

PROGRAMA:

NAME


perlfaq5 - Mga File at Format

VERSION


bersyon 5.021009

DESCRIPTION


Ang seksyong ito ay tumatalakay sa I/O at mga isyu sa "f": filehandles, flushing, mga format, at
mga footer.

Gaano do I flush/unbuffer an output filehandle? Bakit dapat I do ito?
(kontribusyon ni brian d foy)

Baka gusto mong basahin ang "Suffering From Buffering" ni Mark Jason Dominus sa
<http://perl.plover.com/FAQs/Buffering.html>.

Karaniwang bina-buffer ng Perl ang output kaya hindi ito gumagawa ng system call para sa bawat bit ng output. Sa pamamagitan ng
nakakatipid ng output, gumagawa ito ng mas kaunting mga mamahaling system call. Halimbawa, sa maliit na ito
ng code, gusto mong mag-print ng tuldok sa screen para sa bawat linyang pinoproseso mo upang panoorin ang
progreso ng iyong programa. Sa halip na makakita ng tuldok para sa bawat linya, bina-buffer ng Perl ang output
at mayroon kang mahabang paghihintay bago ka makakita ng isang hilera ng 50 tuldok nang sabay-sabay:

# mahabang paghihintay, pagkatapos ay hilera ng mga tuldok nang sabay-sabay
habang( <> ) {
i-print ang ".";
i-print ang "\n" maliban kung ++$count % 50;

#... mamahaling line processing operations
}

Upang makayanan ito, kailangan mong i-unbuffer ang output filehandle, sa kasong ito, "STDOUT".
Maaari mong itakda ang espesyal na variable na $| sa isang tunay na halaga (mnemonic: paggawa ng iyong filehandles
"mainit na mainit"):

$|++;

# tuldok na ipinakita kaagad
habang( <> ) {
i-print ang ".";
i-print ang "\n" maliban kung ++$count % 50;

#... mamahaling line processing operations
}

Ang $| ay isa sa mga espesyal na variable ng per-filehandle, kaya ang bawat filehandle ay may sariling kopya
ng halaga nito. Kung gusto mong pagsamahin ang karaniwang output at karaniwang error halimbawa, ikaw
kailangang i-unbuffer ang bawat isa (bagaman maaaring hindi ma-unbuffer ang STDERR bilang default):

{
my $previous_default = piliin(STDOUT); # i-save ang nakaraang default
$|++; # autoflush STDOUT
piliin(STDERR);
$|++; # autoflush STDERR, para makasigurado
piliin($previous_default); # ibalik ang dating default
}

# ngayon ay dapat magpalit . at +
habang(1) {
matulog 1;
i-print ang STDOUT ".";
i-print ang STDERR "+";
i-print ang STDOUT "\n" maliban kung ++$count % 25;
}

Bukod sa $| espesyal na variable, maaari mong gamitin ang "binmode" upang bigyan ang iyong filehandle ng ":unix"
layer, na hindi na-buffer:

binmode( STDOUT, ":unix" );

habang(1) {
matulog 1;
i-print ang ".";
i-print ang "\n" maliban kung ++$count % 50;
}

Para sa higit pang impormasyon sa mga layer ng output, tingnan ang mga entry para sa "binmode" at buksan sa perlfunc,
at ang dokumentasyon ng PerlIO module.

Kung gumagamit ka ng IO::Handle o isa sa mga subclass nito, maaari mong tawagan ang "autoflush" na paraan
upang baguhin ang mga setting ng filehandle:

gamitin ang IO::Handle;
buksan ang aking( $io_fh ), ">", "output.txt";
$io_fh->autoflush(1);

Ang IO::Handle object ay mayroon ding "flush" na paraan. Maaari mong i-flush ang buffer anumang oras mo
gusto nang walang auto-buffering

$io_fh->flush;

Gaano do I magbago, tanggalin, or isingit a linya in a file, or apendend sa ang simula of a file?
(kontribusyon ni brian d foy)

Kasama sa pangunahing ideya ng pagpasok, pagbabago, o pagtanggal ng linya mula sa isang text file
pagbabasa at pag-print ng file hanggang sa puntong gusto mong gawin ang pagbabago, paggawa ng pagbabago,
pagkatapos ay basahin at i-print ang natitirang bahagi ng file. Ang Perl ay hindi nagbibigay ng random na access sa
mga linya (lalo na dahil ang record input separator, $/, ay nababago), kahit na ang mga module ay ganoon
bilang Tie::File ay maaaring pekein ito.

Ang isang Perl program upang gawin ang mga gawaing ito ay tumatagal ng pangunahing paraan ng pagbubukas ng isang file, pag-print nito
linya, pagkatapos ay isara ang file:

buksan ang aking $in, '<', $file o mamatay "Hindi mabasa ang lumang file: $!";
buksan ang aking $out, '>', "$file.new" o mamatay "Hindi magsulat ng bagong file: $!";

habang( <$in> ) {
i-print ang $out $_;
}

isara ang $out;

Sa loob ng pangunahing form na iyon, idagdag ang mga bahagi na kailangan mong ipasok, baguhin, o tanggalin ang mga linya.

Upang i-prepend ang mga linya sa simula, i-print ang mga linyang iyon bago mo ipasok ang loop na nagpi-print
ang mga umiiral na linya.

buksan ang aking $in, '<', $file o mamatay "Hindi mabasa ang lumang file: $!";
buksan ang aking $out, '>', "$file.new" o mamatay "Hindi magsulat ng bagong file: $!";

print $out "# Idagdag ang linyang ito sa itaas\n"; # <--- ETO ANG MAGIC

habang( <$in> ) {
i-print ang $out $_;
}

isara ang $out;

Upang baguhin ang mga kasalukuyang linya, ipasok ang code upang baguhin ang mga linya sa loob ng "habang" loop. Sa
sa kasong ito, hinahanap ng code ang lahat ng lowercase na bersyon ng "perl" at pinalalaki ang mga ito. Ang
nangyayari para sa bawat linya, kaya siguraduhin na dapat mong gawin iyon sa bawat linya!

buksan ang aking $in, '<', $file o mamatay "Hindi mabasa ang lumang file: $!";
buksan ang aking $out, '>', "$file.new" o mamatay "Hindi magsulat ng bagong file: $!";

print $out "# Idagdag ang linyang ito sa itaas\n";

habang( <$in> ) {
s/\b(perl)\b/Perl/g;
i-print ang $out $_;
}

isara ang $out;

Upang baguhin lamang ang isang partikular na linya, ang numero ng linya ng input, $., ay kapaki-pakinabang. Unang basahin at
i-print ang mga linya hanggang sa gusto mong baguhin. Susunod, basahin ang solong linya na gusto mo
baguhin, palitan ito, at i-print ito. Pagkatapos nito, basahin ang natitirang mga linya at i-print ang mga iyon:

while( <$in> ) { # i-print ang mga linya bago ang pagbabago
i-print ang $out $_;
huling kung $. == 4; # numero ng linya bago baguhin
}

aking $line = <$in>;
$line =~ s/\b(perl)\b/Perl/g;
i-print ang $out $line;

while( <$in> ) { # i-print ang natitirang mga linya
i-print ang $out $_;
}

Upang laktawan ang mga linya, gamitin ang mga looping na kontrol. Ang "susunod" sa halimbawang ito ay lumalaktaw sa mga linya ng komento,
at ihihinto ng "huling" ang lahat ng pagproseso sa sandaling makatagpo ito ng alinman sa "__END__" o "__DATA__".

habang( <$in> ) {
susunod kung /^\s+#/; # laktawan ang mga linya ng komento
huling kung /^__(END|DATA)__$/; # stop sa dulo ng code marker
i-print ang $out $_;
}

Gawin ang parehong uri ng bagay upang tanggalin ang isang partikular na linya sa pamamagitan ng paggamit ng "susunod" upang laktawan ang mga linya
ayaw mong magpakita sa output. Nilaktawan ng halimbawang ito ang bawat ikalimang linya:

habang( <$in> ) {
susunod maliban kung $. % 5;
i-print ang $out $_;
}

Kung, para sa ilang kakaibang dahilan, gusto mo talagang makita ang buong file nang sabay-sabay kaysa sa
sa pagpoproseso ng linya-by-line, maaari mo itong i-slurp (hangga't maaari mong kasya ang buong bagay
alaala!):

buksan ang aking $in, '<', $file o mamatay "Hindi mabasa ang lumang file: $!"
buksan ang aking $out, '>', "$file.new" o mamatay "Hindi magsulat ng bagong file: $!";

my $content = gawin { local $/; <$in> }; # slurp!

# gawin mo ang iyong magic dito

i-print ang $out $content;

Ang mga module tulad ng Path::Tiny at Tie::File ay makakatulong din diyan. Kung kaya mo, gayunpaman,
iwasang basahin ang buong file nang sabay-sabay. Hindi ibabalik ni Perl ang memoryang iyon sa operating
system hanggang sa matapos ang proseso.

Maaari mo ring gamitin ang Perl one-liners upang baguhin ang isang file sa lugar. Ang mga sumusunod ay nagbabago lahat
'Fred' sa 'Barney' sa inFile.txt, pag-overwrite sa file ng mga bagong nilalaman. Kasama ang
"-p" switch, binalot ni Perl ang isang "habang" loop sa paligid ng code na iyong tinukoy ng "-e", at "-i"
Ino-on ang in-place na pag-edit. Ang kasalukuyang linya ay nasa $_. Gamit ang "-p", awtomatikong nagpi-print si Perl
ang halaga ng $_ sa dulo ng loop. Tingnan ang perlrun para sa higit pang mga detalye.

perl -pi -e 's/Fred/Barney/' saFile.txt

Upang gumawa ng backup ng "inFile.txt", bigyan ang "-i" ng extension ng file upang idagdag:

perl -pi.bak -e 's/Fred/Barney/' inFile.txt

Upang baguhin lamang ang ikalimang linya, maaari kang magdagdag ng isang pagsubok sa pagsusuri $., ang numero ng linya ng input, pagkatapos
gawin lamang ang operasyon kapag pumasa ang pagsubok:

perl -pi -e 's/Fred/Barney/ kung $. == 5' inFile.txt

Upang magdagdag ng mga linya bago ang isang partikular na linya, maaari kang magdagdag ng linya (o mga linya!) bago mag-print si Perl ng $_:

perl -pi -e 'print "Ilagay bago ang ikatlong linya\n" kung $. == 3' inFile.txt

Maaari ka ring magdagdag ng isang linya sa simula ng isang file, dahil ang kasalukuyang linya ay nagpi-print sa
dulo ng loop:

perl -pi -e 'print "Ilagay bago ang unang linya\n" kung $. == 1' inFile.txt

Upang magpasok ng isang linya pagkatapos ng isa na nasa file, gamitin ang "-n" switch. Parang "-p" lang.
maliban na hindi ito nagpi-print ng $_ sa dulo ng loop, kaya kailangan mong gawin iyon mismo.
Sa kasong ito, i-print muna ang $_, pagkatapos ay i-print ang linya na gusto mong idagdag.

perl -ni -e 'print; i-print ang "Ilagay pagkatapos ng ikalimang linya\n" kung $. == 5' inFile.txt

Para magtanggal ng mga linya, i-print lang ang mga gusto mo.

perl -ni -e 'i-print kung /d/' saFile.txt

Gaano do I bilangin ang numero of linya in a file?
(kontribusyon ni brian d foy)

Sa konsepto, ang pinakamadaling paraan upang mabilang ang mga linya sa isang file ay basahin lamang ang mga ito at
bilangin sila:

ang aking $count = 0;
while( <$fh> ) { $count++; }

Gayunpaman, hindi mo kailangang bilangin ang mga ito sa iyong sarili, dahil ginagawa na iyon ni Perl
ang $. variable, na kasalukuyang numero ng linya mula sa huling filehandle na nabasa:

1 habang( <$fh> );
ang aking $count = $.;

Kung gusto mong gumamit ng $., maaari mo itong bawasan sa isang simpleng one-liner, tulad ng isa sa mga ito:

% perl -lne '} print $.; {' file

% perl -lne 'END { print $. }' file

Ang mga iyon ay maaaring maging hindi epektibo bagaman. Kung hindi sila sapat na mabilis para sa iyo, maaari mo na lang
basahin ang mga chunks ng data at bilangin ang bilang ng mga bagong linya:

aking $lines = 0;
buksan ang aking($fh), '<:raw', $filename o mamatay "Hindi mabuksan ang $filename: $!";
habang( sysread $fh, $buffer, 4096 ) {
$lines += ( $buffer =~ tr/\n// );
}
malapit $fh;

Gayunpaman, hindi iyon gagana kung ang pagtatapos ng linya ay hindi isang bagong linya. Baka baguhin mo yan
"tr///" sa isang "s///" para mabilang mo kung ilang beses ang input record separator, $/,
nagpakita:

aking $lines = 0;
buksan ang aking($fh), '<:raw', $filename o mamatay "Hindi mabuksan ang $filename: $!";
habang( sysread $fh, $buffer, 4096 ) {
$lines += ( $buffer =~ s|$/||g; );
}
malapit $fh;

Kung hindi mo iniisip na mag-shell out, ang "wc" na utos ay karaniwang pinakamabilis, kahit na may
dagdag na interprocess overhead. Tiyakin na mayroon kang hindi nabahiran na filename kahit na:

#!perl -T

$ENV{PATH} = undef;

aking $lines;
if( $filename =~ /^([0-9a-z_.]+)\z/ ) {
$linya = `/usr/bin/wc -l $1`
chomp $lines;
}

Gaano do I alisin ang huli N linya mula a file?
(kontribusyon ni brian d foy)

Ang pinakamadaling solusyon sa haka-haka ay ang bilangin ang mga linya sa file pagkatapos ay magsimula sa
simula at i-print ang bilang ng mga linya (minus ang huling N) sa isang bagong file.

Kadalasan, ang tunay na tanong ay kung paano mo matatanggal ang huling N linya nang hindi gumagawa ng higit pa
kaysa sa isang pagpasa sa file, o kung paano gawin ito nang walang maraming pagkopya. Ang madaling konsepto ay
ang mahirap na katotohanan kapag mayroon kang milyun-milyong linya sa iyong file.

Ang isang trick ay ang paggamit ng File::ReadBackwards, na magsisimula sa dulo ng file. Modyul na iyon
ay nagbibigay ng isang bagay na bumabalot sa tunay na filehandle upang gawing madali para sa iyo na lumipat sa paligid
ang file. Sa sandaling makarating ka sa lugar na kailangan mo, maaari mong makuha ang aktwal na filehandle at magtrabaho
kasama ito bilang normal. Sa kasong ito, makukuha mo ang posisyon ng file sa dulo ng huling linya mo
nais na panatilihin at putulin ang file sa puntong iyon:

gamitin ang File::ReadBackwards;

ang aking $filename = 'test.txt';
aking $Lines_to_truncate = 2;

my $bw = File::ReadBackwards->new( $filename )
o mamatay "Hindi makabasa nang pabalik sa [$filename]: $!";

aking $lines_from_end = 0;
hanggang( $bw->eof o $lines_from_end == $Lines_to_truncate ) {
print "Nakuha: ", $bw->readline;
$lines_from_end++;
}

truncate( $filename, $bw->tell );

Ang File::ReadBackwards module ay mayroon ding kalamangan sa pagtatakda ng input record
separator sa isang regular na expression.

Maaari mo ring gamitin ang Tie::File module na nagbibigay-daan sa iyong i-access ang mga linya sa pamamagitan ng isang nakatali
array. Maaari kang gumamit ng mga normal na operasyon ng array upang baguhin ang iyong file, kabilang ang pagtatakda ng huli
index at gamit ang "splice".

Gaano maaari I gamitin kay Perl "-ako" opsyon mula sa loob ng a programa?
Itinatakda ng "-i" ang halaga ng variable na $^I ng Perl, na nakakaapekto naman sa pag-uugali ng "<>";
tingnan ang perlrun para sa higit pang mga detalye. Sa pamamagitan ng direktang pagbabago sa naaangkop na mga variable, maaari kang makakuha
ang parehong pag-uugali sa loob ng isang mas malaking programa. Halimbawa:

# ...
{
local($^I, @ARGV) = ('.orig', glob("*.c"));
habang (<>) {
kung ($. == 1) {
print "Ang linyang ito ay dapat lumitaw sa tuktok ng bawat file\n";
}
s/\b(p)earl\b/${1}erl/i; # Tamang typo, pinapanatili ang kaso
i-print;
isara ang ARGV kung eof; # I-reset ang $.
}
}
# $^Ako at @ARGV ay bumalik sa kanilang mga dating halaga dito

Binabago ng block na ito ang lahat ng ".c" na file sa kasalukuyang direktoryo, na nag-iiwan ng backup ng
orihinal na data mula sa bawat file sa isang bagong ".c.orig" na file.

Gaano maaari I kopyahin a file?
(kontribusyon ni brian d foy)

Gamitin ang File::Copy module. Ito ay kasama ng Perl at maaaring gumawa ng isang tunay na kopya sa mga file system,
at ginagawa nito ang magic sa isang portable na paraan.

gamitin ang File::Copy;

copy( $original, $new_copy ) o mamatay "Nabigo ang pagkopya: $!";

Kung hindi mo magagamit ang File::Copy, kakailanganin mong gawin ang gawain nang mag-isa: buksan ang orihinal na file,
buksan ang patutunguhang file, pagkatapos ay i-print sa patutunguhang file habang binabasa mo ang orihinal.
Kailangan mo ring tandaan na kopyahin ang mga pahintulot, may-ari, at pangkat sa bagong file.

Gaano do I gumawa a pansamantala file pangalan?
Kung hindi mo kailangang malaman ang pangalan ng file, maaari mong gamitin ang "open()" na may "undef" sa lugar
ng pangalan ng file. Sa Perl 5.8 o mas bago, ang function na "open()" ay lumilikha ng anonymous
pansamantalang file:

buksan ang aking $tmp, '+>', undef or die $!;

Kung hindi, maaari mong gamitin ang File::Temp module.

gamitin ang File::Temp qw/ tempfile tempdir /;

my $dir = tempdir( CLEANUP => 1 );
($fh, $filename) = tempfile( DIR => $dir );

# o kung hindi mo kailangang malaman ang filename

my $fh = tempfile( DIR => $dir );

Ang File::Temp ay isang karaniwang module mula noong Perl 5.6.1. Kung wala kang moderno
sapat na Perl na naka-install, gamitin ang "new_tmpfile" na paraan ng klase mula sa IO::File module upang makakuha
binuksan ang isang filehandle para sa pagbabasa at pagsusulat. Gamitin ito kung hindi mo kailangang malaman ang file
pangalan:

gamitin ang IO::File;
my $fh = IO::File->new_tmpfile()
o mamatay "Hindi makagawa ng bagong pansamantalang file: $!";

Kung nakatuon ka sa paggawa ng pansamantalang file sa pamamagitan ng kamay, gamitin ang process ID at/o ang
kasalukuyang halaga ng oras. Kung kailangan mong magkaroon ng maraming pansamantalang file sa isang proseso, gumamit ng a
counter:

MAGSIMULA {
gumamit ng Fcntl;
gamitin ang File::Spec;
my $temp_dir = File::Spec->tmpdir();
my $file_base = sprintf "%d-%d-0000", $$, oras;
my $base_name = File::Spec->catfile($temp_dir, $file_base);

sub temp_file {
aking $fh;
ang aking $count = 0;
hanggang( tinukoy(fileno($fh)) || $count++ > 100 ) {
$base_name =~ s/-(\d+)$/"-" . (1 + $1)/e;
Kinakailangan ang # O_EXCL para sa mga kadahilanang pangseguridad.
sysopen $fh, $base_name, O_WRONLY|O_EXCL|O_CREAT;
}

kung( tinukoy ang fileno($fh) ) {
return ($fh, $base_name);
}
tao {
bumalik ();
}
}
}

Gaano maaari I manipulahin fixed-record-length mga file?
Ang pinaka-epektibong paraan ay ang paggamit pack() at i-unpack(). Ito ay mas mabilis kaysa sa paggamit substr()
kapag kumukuha ng marami, maraming string. Ito ay mas mabagal para sa iilan lamang.

Narito ang isang sample na tipak ng code upang masira at muling pagsamahin ang ilang nakapirming format
input lines, sa kasong ito mula sa output ng isang normal, Berkeley-style ps:

# sample na linya ng input:
# 15158 p5 T 0:00 perl /home/tchrist/scripts/now-what
aking $PS_T = 'A6 A4 A7 A5 A*';
buksan ang aking $ps, '-|', 'ps';
print scalar <$ps>;
my @fields = qw(pid tt stat time command );
habang (<$ps>) {
ang aking %proseso;
@process{@fields} = unpack ($PS_T, $_);
para sa aking $field ( @fields ) {
i-print ang "$field: <$process{$field}>\n";
}
i-print ang 'line=', pack ($PS_T, @process{@fields} ), "\n";
}

Gumamit kami ng hash slice para madaling mahawakan ang mga field ng bawat row. Pag-iimbak ng
Pinapadali ng mga key sa isang array na patakbuhin ang mga ito bilang isang grupo o i-loop ang mga ito gamit ang "for".
Iniiwasan din nito ang pagdumi sa programa ng mga pandaigdigang variable at paggamit ng mga simbolikong sanggunian.

Gaano maaari I gumawa a filehandle lokal sa a subroutine? Gaano do I pumasa filehandles sa pagitan ng
mga subroutine? Gaano do I gumawa an ayos of filehandles?
Mula sa perl5.6, bukas() autovivifies file at directory handle bilang mga sanggunian kung ipapasa mo ito
isang uninitialized scalar variable. Maaari mong ipasa ang mga sangguniang ito tulad ng iba
scalar, at gamitin ang mga ito sa lugar ng pinangalanang mga hawakan.

buksan ang aking $fh, $file_name;

buksan ang lokal na $fh, $file_name;

print $fh "Hello World!\n";

process_file( $fh );

Kung gusto mo, maaari mong iimbak ang mga filehandle na ito sa isang array o hash. Kung ma-access mo sila
direkta, hindi sila simpleng mga scalar at kailangan mong magbigay ng "print" ng kaunting tulong sa pamamagitan ng paglalagay
ang filehandle reference sa braces. Ang Perl ay maaari lamang malaman ito sa sarili nitong kapag ang
Ang sanggunian ng filehandle ay isang simpleng scalar.

aking @fhs = ($fh1, $fh2, $fh3 );

para sa( $i = 0; $i <= $#fhs; $i++ ) {
print {$fhs[$i]} "isa pang Perl na sagot, \n";
}

Bago ang perl5.6, kailangan mong harapin ang iba't ibang mga idyoma ng typeglob na maaari mong makita sa mas luma
code.

buksan ang FILE, "> $filename";
process_typeglob( *FILE );
process_reference( \*FILE );

sub process_typeglob { local *FH = shift; i-print ang FH "Typeglob!" }
sub process_reference { local $fh = shift; print $fh "Sanggunian!" }

Kung nais mong lumikha ng maraming hindi kilalang mga hawakan, dapat mong tingnan ang Simbolo o
IO:: Pangasiwaan ang mga module.

Gaano maaari I gamitin a filehandle hindi direkta?
Ang hindi direktang filehandle ay ang paggamit ng isang bagay maliban sa isang simbolo sa isang lugar na a
filehandle ay inaasahan. Narito ang mga paraan upang makakuha ng mga hindi direktang filehandle:

$fh = SOME_FH; # bareword is strict-subs pagalit
$fh = "SOME_FH"; # strict-refs pagalit; same package lang
$fh = *SOME_FH; # typeglob
$fh = \*SOME_FH; # ref sa typeglob (bless-able)
$fh = *SOME_FH{IO}; # pinagpalang IO::Hawain mula sa *SOME_FH typeglob

O, maaari mong gamitin ang "bagong" paraan mula sa isa sa mga module ng IO::* para gumawa ng anonymous
filehandle at iimbak iyon sa isang scalar variable.

gamitin ang IO::Handle; # 5.004 o mas mataas
my $fh = IO::Handle->new();

Pagkatapos ay gamitin ang alinman sa mga iyon tulad ng gagawin mo sa isang normal na filehandle. Kahit saan inaasahan ni Perl a
filehandle, maaaring gumamit ng hindi direktang filehandle. Ang isang hindi direktang filehandle ay isang
scalar variable na naglalaman ng filehandle. Mga function tulad ng "print", "open", "seek", o ang
" " tatanggapin ng operator ng diamond ang alinman sa pinangalanang filehandle o isang scalar variable
naglalaman ng isa:

($ifh, $ofh, $efh) = (*STDIN, *STDOUT, *STDERR);
print $ofh "I-type ito: ";
ang aking $got = <$ifh>
print $efh "Ano iyon: $got";

Kung nagpapasa ka ng filehandle sa isang function, maaari mong isulat ang function sa dalawang paraan:

sub accept_fh {
aking $fh = shift;
print $fh "Ipinapadala sa hindi direktang filehandle\n";
}

O maaari nitong i-localize ang isang typeglob at direktang gamitin ang filehandle:

sub accept_fh {
lokal *FH = shift;
print FH "Ipinapadala sa naisalokal na filehandle\n";
}

Ang parehong mga estilo ay gumagana sa alinman sa mga bagay o mga typeglob ng totoong filehandle. (Maaaring sila rin
gumana sa mga string sa ilalim ng ilang mga pangyayari, ngunit ito ay mapanganib.)

accept_fh(*STDOUT);
accept_fh($handle);

Sa mga halimbawa sa itaas, itinalaga namin ang filehandle sa isang scalar variable bago ito gamitin.
Iyon ay dahil simpleng scalar variable lang, hindi mga expression o subscript ng mga hash o
arrays, ay maaaring gamitin sa mga built-in tulad ng "print", "printf", o ang diamond operator. Gamit
isang bagay maliban sa isang simpleng scalar variable bilang isang filehandle ay labag sa batas at hindi ito gagawin
i-compile:

aking @fd = (*STDIN, *STDOUT, *STDERR);
print $fd[1] "I-type ito: "; # MALI
my $got = <$fd[0]> # WRONG
print $fd[2] "Ano iyon: $got"; # MALI

Gamit ang "print" at "printf", malalagpasan mo ito sa pamamagitan ng paggamit ng block at expression kung saan
ilalagay mo ang filehandle:

print { $fd[1] } "nakakatawang bagay\n";
printf { $fd[1] } "Kawawa ang mahihirap %x.\n", 3_735_928_559;
# Kawawa naman ang kawawang deadbeef.

Ang bloke na iyon ay isang wastong bloke tulad ng iba pa, kaya maaari kang maglagay ng mas kumplikadong code doon.
Ipinapadala nito ang mensahe sa isa sa dalawang lugar:

ang aking $ok = -x"/bin/cat";
print { $ok ? $fd[1] : $fd[2] } "cat stat $ok\n";
print { $fd[ 1+ ($ok || 0) ] } "cat stat $ok\n";

Ang diskarteng ito ng pagtrato sa "print" at "printf" tulad ng mga object method na tawag ay hindi gumagana
ang diamond operator. Iyon ay dahil ito ay isang tunay na operator, hindi lamang isang function na may a
argumento na walang kuwit. Ipagpalagay na nag-iimbak ka ng mga typeglob sa iyong istraktura tulad ng ginawa namin
sa itaas, maaari mong gamitin ang built-in na function na pinangalanang "readline" upang magbasa ng isang record bilang "<>"
ginagawa. Dahil sa inisyal na ipinakita sa itaas para sa @fd, gagana ito, ngunit dahil lamang
Basahin ang linya() nangangailangan ng typeglob. Hindi ito gumagana sa mga bagay o string, na maaaring a
bug na hindi pa namin naayos.

$got = readline($fd[0]);

Tandaan na ang flakiness ng indirect filehandles ay hindi nauugnay sa kung
ang mga ito ay mga string, typeglobs, mga bagay, o anumang bagay. Ito ang syntax ng pangunahing
mga operator. Ang paglalaro ng object game ay hindi nakakatulong sa iyo dito.

Gaano maaari I itakda up a pampaa format sa be ginamit sa sumulat ()?
Walang builtin na paraan upang gawin ito, ngunit ang perlform ay may ilang mga diskarte upang gawin ito
posible para sa matapang na hacker.

Gaano maaari I sumulat () sa a string?
(kontribusyon ni brian d foy)

Kung gusto mong "magsulat" sa isang string, kailangan mo lang isang filehandle sa isang string,
na nagawa ni Perl mula noong Perl 5.6:

buksan ang FH, '>', \my $string;
isulat (FH);

Dahil gusto mong maging isang mahusay na programmer, malamang na gusto mong gumamit ng lexical filehandle,
kahit na ang mga format ay idinisenyo upang gumana sa mga bareword filehandles mula noong default
kinukuha ng mga pangalan ng format ang pangalan ng filehandle. Gayunpaman, makokontrol mo ito sa ilang Perl
espesyal na per-filehandle variable: $^, na nagpapangalan sa top-of-page na format, at $~ which
ipinapakita ang format ng linya. Kailangan mong baguhin ang default na filehandle para itakda ang mga variable na ito:

buksan ang aking($fh), '>', \my $string;

{ # set per-filehandle variable
aking $old_fh = piliin( $fh );
$~ = 'HAYOP';
$^ = 'ANIMAL_TOP';
piliin( $old_fh );
}

format ANIMAL_TOP =
Pangalan ng Uri ng ID
.

format HAYOP =
@## @<<< @<<<<<<<<<<<<
$id, $type, $name
.

Bagama't ang pagsulat ay maaaring gumana sa mga variable na lexical o package, kahit anong mga variable ang iyong ginagamit ay mayroon
sa saklaw sa format. Malamang na nangangahulugan iyon na gusto mong i-localize ang ilang package
variable

{
local( $id, $type, $name ) = qw(12 cat Buster );
isulat($fh);
}

i-print ang $string;

Mayroon ding ilang mga trick na maaari mong laruin gamit ang "formline" at ang variable ng accumulator
$^A, ngunit nawalan ka ng maraming halaga ng mga format dahil hindi hahawakan ng "formline" ang paging at
iba pa. Napupunta ka sa muling pagpapatupad ng mga format kapag ginamit mo ang mga ito.

Gaano maaari I buksan a filehandle sa a string?
(na iniambag ni Peter J. Holzer, [protektado ng email])

Dahil ang Perl 5.8.0 isang file handle na tumutukoy sa isang string ay maaaring malikha sa pamamagitan ng pagtawag bukas na may a
reference sa string na iyon sa halip na ang filename. Magagamit na ang file handle na ito
magbasa mula o sumulat sa string:

open(my $fh, '>', \$string) o mamatay "Hindi mabuksan ang string para sa pagsusulat";
i-print ang $fh "foo\n";
i-print ang $fh "bar\n"; Ang # $string ay naglalaman na ngayon ng "foo\nbar\n"

open(my $fh, '<', \$string) o mamatay "Hindi mabuksan ang string para sa pagbabasa";
aking $x = <$fh>; Ang # $x ay naglalaman na ngayon ng "foo\n"

Sa mga mas lumang bersyon ng Perl, ang IO::String module ay nagbibigay ng katulad na functionality.

Gaano maaari I output my numero sa mga kuwit idinagdag?
(kontribusyon nina brian d foy at Benjamin Goldberg)

Maaari mong gamitin ang Number::Format upang paghiwalayin ang mga lugar sa isang numero. Pinangangasiwaan nito ang lokal na impormasyon
para sa iyo na gustong maglagay ng mga full stop sa halip (o anumang bagay na gusto nila
gamitin, talaga).

Ang subroutine na ito ay magdaragdag ng mga kuwit sa iyong numero:

sub commify {
lokal na $_ = shift;
1 habang s/^([-+]?\d+)(\d{3})/$1,$2/;
ibalik ang $_;
}

Ang regex na ito mula kay Benjamin Goldberg ay magdaragdag ng mga kuwit sa mga numero:

s/(^[-+]?\d+?(?=(?>(?:\d{3})+)(?!\d))|\G\d{3}(?=\d) )/$1,/g;

Mas madaling makita sa mga komento:

s/(
^[-+]? # simula ng numero.
\d+? # unang digit bago ang unang kuwit
(?= # na sinundan ng, (ngunit hindi kasama sa laban):
(?>(?:\d{3})+) # ilang positibong multiple ng tatlong digit.
(?!\d) # isang *eksaktong* maramihang, hindi x * 3 + 1 o anuman.
)
| # o:
\G\d{3} # pagkatapos ng huling pangkat, kumuha ng tatlong digit
(?=\d) # ngunit kailangan nilang magkaroon ng higit pang mga digit pagkatapos nila.
)/$1,/xg;

Gaano maaari I Isalin mga accent (~) in a filename?
Gamitin ang operator na <> ("glob()"), na nakadokumento sa perlfunc. Mga bersyon ng Perl na mas luma sa 5.6
nangangailangan na mayroon kang isang shell na naka-install na groks tildes. Ang mga susunod na bersyon ng Perl ay mayroon
ang feature na ito ay built in. Ang File::KGlob module (available mula sa CPAN) ay nagbibigay ng mas portable
pag-andar ng glob.

Sa loob ng Perl, maaari mong gamitin ito nang direkta:

$filename =~ s{
^ ~ # humanap ng nangungunang tilde
( # i-save ito sa $1
[^/] # isang non-slash na character
* # naulit ng 0 o higit pang beses (ang ibig sabihin ng 0 ay ako)
)
}{
$1
? (getpwnam($1))[7]
: ( $ENV{HOME} || $ENV{LOGDIR} )
}ex;

Gaano Dumating kailan I buksan a file basa sulat it wipes it labas?
Dahil gumagamit ka ng isang bagay na tulad nito, na pinuputol ang file pagkatapos nagbibigay sa iyo ng pagbasa-
access sa pagsulat:

buksan ang aking $fh, '+>', '/path/name'; # MALI (halos palagi)

Oops. Sa halip ay dapat mong gamitin ito, na mabibigo kung ang file ay hindi umiiral:

buksan ang aking $fh, '+<', '/path/name'; # bukas para sa pag-update

Ang paggamit ng ">" ay palaging nagkukunwari o lumilikha. Ang paggamit ng "<" ay hindi rin ginagawa. Ang "+" ay hindi nagbabago
na ito.

Narito ang mga halimbawa ng maraming uri ng pagbubukas ng file. Ang mga gumagamit ng "sysopen" lahat ay ipinapalagay na
nakuha mo ang mga constant mula sa Fcntl:

gumamit ng Fcntl;

Upang buksan ang file para sa pagbabasa:

buksan ang aking $fh, '<', $path o mamatay $!;
sysopen ang aking $fh, $path, O_RDONLY o mamatay $!;

Upang buksan ang file para sa pagsusulat, lumikha ng bagong file kung kinakailangan o kung hindi ay putulin ang lumang file:

buksan ang aking $fh, '>', $path o mamatay $!;
sysopen ang aking $fh, $path, O_WRONLY|O_TRUNC|O_CREAT o mamatay $!;
sysopen ang aking $fh, $path, O_WRONLY|O_TRUNC|O_CREAT, 0666 o mamatay $!;

Upang buksan ang file para sa pagsusulat, lumikha ng bagong file, hindi dapat umiral ang file:

sysopen ang aking $fh, $path, O_WRONLY|O_EXCL|O_CREAT o mamatay $!;
sysopen ang aking $fh, $path, O_WRONLY|O_EXCL|O_CREAT, 0666 o mamatay $!;

Upang buksan ang file para sa pagdaragdag, lumikha kung kinakailangan:

buksan ang aking $fh, '>>' $path o mamatay $!;
sysopen ang aking $fh, $path, O_WRONLY|O_APPEND|O_CREAT or die $!;
sysopen my $fh, $path, O_WRONLY|O_APPEND|O_CREAT, 0666 or die $!;

Upang buksan ang file para sa pagdaragdag, ang file ay dapat na umiiral:

sysopen ang aking $fh, $path, O_WRONLY|O_APPEND o mamatay $!;

Upang buksan ang file para sa pag-update, dapat na umiiral ang file:

buksan ang aking $fh, '+<', $path o mamatay $!;
sysopen ang aking $fh, $path, O_RDWR o mamatay $!;

Upang buksan ang file para sa pag-update, gumawa ng file kung kinakailangan:

sysopen ang aking $fh, $path, O_RDWR|O_CREAT o mamatay $!;
sysopen ang aking $fh, $path, O_RDWR|O_CREAT, 0666 o mamatay $!;

Upang buksan ang file para sa pag-update, hindi dapat umiral ang file:

sysopen ang aking $fh, $path, O_RDWR|O_EXCL|O_CREAT o mamatay $!;
sysopen ang aking $fh, $path, O_RDWR|O_EXCL|O_CREAT, 0666 o mamatay $!;

Upang magbukas ng file nang hindi nakaharang, lumilikha kung kinakailangan:

sysopen ang aking $fh, '/foo/somefile', O_WRONLY|O_NDELAY|O_CREAT
o mamatay "hindi mabuksan /foo/somefile: $!":

Maging babala na ang paggawa o pagtanggal ng mga file ay hindi ginagarantiyahan na isang atomic
operasyon sa NFS. Ibig sabihin, maaaring parehong matagumpay na magawa o i-unlink ng dalawang proseso ang
parehong file! Samakatuwid ang O_EXCL ay hindi kasing-eksklusibo gaya ng gusto mo.

Tingnan din ang perlopentut.

Bakit do I kung minsan makuha an "Pagtatalo listahan masyado mahaba" kailan I gamitin <*>?
Ang "<>" operator ay nagsasagawa ng globbing operation (tingnan sa itaas). Sa mga bersyon ng Perl mas maaga
kaysa sa v5.6.0, ang panloob glob() mga tinidor ng operator csh(1) upang gawin ang aktwal na pagpapalawak ng glob,
ngunit hindi mahawakan ng csh ang higit sa 127 na mga item at sa gayon ay nagbibigay ng mensahe ng error na "Listahan din ng argumento
mahaba". Ang mga taong nag-install ng tcsh bilang csh ay hindi magkakaroon ng ganitong problema, ngunit maaaring ang kanilang mga gumagamit
nagulat ito.

Upang makayanan ito, mag-upgrade sa Perl v5.6.0 o mas bago, gawin ang glob sa iyong sarili
readdir() at mga pattern, o gumamit ng module tulad ng File::Glob, isa na hindi gumagamit ng shell sa
gumawa ng globbing.

Gaano maaari I buksan a file sa a nangunguna ">" or trailing mga blangko?
(kontribusyon ni Brian McCauley)

Ang espesyal na dalawang-argumentong anyo ng Perl's bukas() hindi pinapansin ng function ang trailing na mga blangko sa
mga filename at hinuhulaan ang mode mula sa ilang mga nangungunang character (o isang sumusunod na "|"). Sa
mas lumang bersyon ng Perl ito ang tanging bersyon ng bukas() at kaya ito ay laganap sa lumang
code at mga libro.

Maliban kung mayroon kang partikular na dahilan upang gamitin ang form na may dalawang argumento dapat mong gamitin ang tatlong-
anyo ng argumento ng bukas() na hindi tinatrato ang anumang mga character sa filename bilang espesyal.

buksan ang aking $fh, "<", " file "; # filename ay " file "
buksan ang aking $fh, ">", ">file"; # filename ay ">file"

Gaano maaari I maaasahan palitan ang pangalan a file?
Kung ang iyong operating system ay sumusuporta sa isang maayos mv(1) utility o katumbas nito sa pagganap,
gumagana ito:

rename($old, $new) o system("mv", $old, $new);

Maaaring mas portable na gamitin ang File::Copy module sa halip. Kopyahin mo na lang sa bago
file sa bagong pangalan (pagsusuri ng mga return value), pagkatapos ay tanggalin ang luma. Hindi talaga ito
ang parehong semantically bilang isang "rename()", na nagpapanatili ng meta-impormasyon tulad ng mga pahintulot,
timestamp, impormasyon ng inode, atbp.

Gaano maaari I ikulong a file?
Binuo na ni Perl kawan() function (tingnan ang perlfunc para sa mga detalye) ay tatawag kawan(2) kung ganoon
mayroon, fcntl(2) kung hindi (sa perl bersyon 5.004 at mas bago), at lockf(3) kung wala
sa dalawang nakaraang sistemang tawag ay umiiral. Sa ilang mga system, maaari pa itong gumamit ng iba
anyo ng katutubong pag-lock. Narito ang ilang mga gotcha sa Perl's kawan():

1. Gumagawa ng isang nakamamatay na error kung wala sa tatlong system ang tumatawag (o ang kanilang malapit na katumbas)
umiiral.

2. lockf(3) ay hindi nagbibigay ng shared locking, at nangangailangan na ang filehandle ay bukas para sa
pagsulat (o pagdaragdag, o pagbasa/pagsusulat).

3. Ilang bersyon ng kawan() hindi ma-lock ang mga file sa isang network (hal. sa NFS file system),
kaya kailangan mong pilitin ang paggamit ng fcntl(2) kapag binuo mo ang Perl. Ngunit kahit na ito ay
nagdududa sa pinakamahusay. Tingnan ang kawan entry ng perlfunc at ang INSTALL file sa pinagmulan
pamamahagi para sa impormasyon sa pagbuo ng Perl para magawa ito.

Dalawang potensyal na hindi halata ngunit tradisyonal na flock semantics ay ang paghihintay nito
walang katiyakan hanggang sa maibigay ang kandado, at ang mga kandado nito ay lamang pagpapayo. Ang nasabing mga
Ang mga discretionary lock ay mas nababaluktot, ngunit nag-aalok ng mas kaunting mga garantiya. Ibig sabihin nito
naka-lock ang mga file gamit ang kawan() maaaring baguhin ng mga program na hindi rin gumagamit kawan().
Ang mga kotse na humihinto para sa mga pulang ilaw ay nagkakasundo sa isa't isa, ngunit hindi sa mga kotseng ganoon
huwag huminto para sa pulang ilaw. Tingnan ang perlport manpage, partikular sa iyong port
dokumentasyon, o ang iyong mga lokal na manpage na partikular sa system para sa mga detalye. Pinakamabuting mag-assume
tradisyonal na pag-uugali kung nagsusulat ka ng mga portable na programa. (Kung hindi, dapat
gaya ng nakasanayan, malayang magsulat para sa mga kakaibang katangian ng iyong system (minsan
tinatawag na "mga tampok"). Ang Slavish na pagsunod sa mga alalahanin sa portability ay hindi dapat makuha sa
paraan para matapos mo ang iyong trabaho.)

Para sa karagdagang impormasyon sa pag-lock ng file, tingnan din ang "File Locking" sa perlopentut kung ikaw
magkaroon nito (bago para sa 5.6).

Bakit hindi pwede I m bukas (FH, ">file.lock")?
Isang karaniwang bit ng code HINDI SA GAMITIN ito ba:

matulog(3) habang -e 'file.lock'; # HUWAG MANGYARING GAMITIN
buksan ang aking $lock, '>', 'file.lock'; # SILANG CODE NA ITO

Ito ay isang klasikong kondisyon ng lahi: gagawa ka ng dalawang hakbang upang gawin ang isang bagay na dapat gawin
isa. Kaya naman ang computer hardware ay nagbibigay ng atomic test-and-set na pagtuturo. Sa teorya,
ito "dapat" gumana:

sysopen ang aking $fh, "file.lock", O_WRONLY|O_EXCL|O_CREAT
o mamatay "hindi mabuksan ang file.lock: $!";

maliban sa nakakalungkot, ang paglikha ng file (at pagtanggal) ay hindi atomic sa NFS, kaya hindi ito gagawin
magtrabaho (hindi bababa sa, hindi sa lahat ng oras) sa net. Iba't ibang mga scheme na kinasasangkutan link() ang inalisan
iminungkahi, ngunit ang mga ito ay may posibilidad na may kinalaman sa abalang paghihintay, na hindi rin kanais-nais.

I pa rin huwag makuha nagla-lock I m gusto sa pagtaas ang numero in ang file. Gaano maaari I do ito?
Wala bang sinuman ang nagsabi sa iyo na ang mga web-page hit counter ay walang silbi? Hindi sila nagbibilang ng numero
ng mga hit, ang mga ito ay isang pag-aaksaya ng oras, at ang mga ito ay nagsisilbi lamang upang i-stroke ang kawalang-kabuluhan ng manunulat. ito ay
mas mahusay na pumili ng isang random na numero; mas makatotohanan sila.

Anyway, ito ang magagawa mo kung hindi mo mapigilan ang sarili mo.

gamitin ang Fcntl qw(:DEFAULT : kawan);
sysopen ang aking $fh, "numfile", O_RDWR|O_CREAT o mamatay "hindi mabuksan ang numfile: $!";
flock $fh, LOCK_EX o mamatay "hindi ma-flock ang numfile: $!";
aking $num = <$fh> || 0;
maghanap ng $fh, 0, 0 o mamatay "hindi ma-rewind ang numfile: $!";
putulin ang $fh, 0 o mamatay "hindi maputol ang numfile: $!";
(i-print ang $fh $num+1, "\n") o mamatay na "hindi magsulat ng numfile: $!";
isara ang $fh o mamatay "hindi maisara ang numfile: $!";

Narito ang isang mas mahusay na web-page hit counter:

$hits = int( (time() - 850_000_000) / Rand(1_000) );

Kung ang bilang ay hindi tumatak sa iyong mga kaibigan, kung gayon ang code ay maaaring. :-)

lahat I gusto sa do is apendend a maliit dami of teksto sa ang dulo of a file. Do I pa rin mayroon sa gamitin
nakakandado?
Kung ikaw ay nasa isang system na wastong nagpapatupad ng "kawan" at ginagamit mo ang halimbawang nakadugtong
code mula sa "perldoc -f flock" lahat ay magiging OK kahit na ang OS na iyong ginagamit ay hindi
ipatupad nang tama ang append mode (kung may ganoong sistema). Kaya kung masaya ka sa paghihigpit
ang iyong sarili sa mga OS na nagpapatupad ng "kawan" (at hindi talaga iyon isang paghihigpit) kung gayon
yan ang dapat mong gawin.

Kung alam mong gagamit ka lang ng isang system na wastong nagpapatupad ng appending
(ibig sabihin, hindi Win32) pagkatapos ay maaari mong alisin ang "maghanap" mula sa code sa nakaraang sagot.

Kung alam mong nagsusulat ka lamang ng code upang tumakbo sa isang OS at filesystem na nagpapatupad
idagdag ang mode nang tama (isang lokal na filesystem sa isang modernong Unix halimbawa), at pinapanatili mo ang
file sa block-buffered mode at sumusulat ka ng mas mababa sa isang buffer-puno ng output sa pagitan ng bawat isa
manu-manong pag-flush ng buffer at ang bawat bufferload ay halos garantisadong isusulatan
ang dulo ng file sa isang tipak nang hindi nakikihalubilo sa output ng sinuman.
Maaari mo ring gamitin ang function na "syswrite" na isang wrapper lang sa paligid ng iyong system
magsulat(2) tawag sa sistema.

Mayroon pa ring maliit na teoretikal na pagkakataon na ang isang signal ay makagambala sa antas ng system
"write()" na operasyon bago makumpleto. May posibilidad din na ang ilang STDIO
ang mga pagpapatupad ay maaaring tumawag sa maraming antas ng system na "write()" kahit na walang laman ang buffer
simulan. Maaaring may ilang mga sistema kung saan ang posibilidad na ito ay nabawasan sa zero, at ito ay
hindi isang alalahanin kapag gumagamit ng ": perlio" sa halip na ang STDIO ng iyong system.

Gaano do I random update a doble file?
Kung sinusubukan mo lang na mag-patch ng isang binary, sa maraming mga kaso, isang bagay na kasing simple nito:

perl -i -pe 's{window manager}{window mangler}g' /usr/bin/emacs

Gayunpaman, kung mayroon kang mga nakapirming laki ng mga tala, maaari kang gumawa ng mas katulad nito:

aking $RECSIZE = 220; # laki ng record, sa bytes
aking $recno = 37; # kung aling tala ang ia-update
buksan ang aking $fh, '+<', 'somewhere' o mamatay "hindi makapag-update sa isang lugar: $!";
humanap ng $fh, $recno * $RECSIZE, 0;
basahin ang $fh, $record, $RECSIZE == $RECSIZE o mamatay "hindi mabasa ang record $recno: $!";
# munge ang record
humanap ng $fh, -$RECSIZE, 1;
i-print ang $fh $record;
malapit $fh;

Ang pag-lock at pagsuri ng error ay naiwan bilang isang ehersisyo para sa mambabasa. Huwag kalimutan ang mga ito o
magsisisi ka talaga.

Gaano do I makuha a mga file timestamp in perl?
Kung gusto mong kunin ang oras kung kailan huling nabasa, naisulat, o nakuha ang file
nagbago ang meta-data (may-ari, atbp), ginagamit mo ang -A, -M, O -C file test operations bilang
dokumentado sa perlfunc. Kinukuha nito ang edad ng file (sinusukat laban sa simula-
oras ng iyong programa) sa mga araw bilang isang numero ng floating point. Ang ilang mga platform ay maaaring hindi lahat
ng mga panahong ito. Tingnan ang perlport para sa mga detalye. Upang makuha ang "raw" na oras sa mga segundo mula noong
epoch, tatawagan mo ang stat function, pagkatapos ay gamitin ang "localtime()", "gmtime()", o
"POSIX::strftime()" para i-convert ito sa form na nababasa ng tao.

Narito ang isang halimbawa:

aking $write_secs = (stat($file))[9];
printf "na-update ang file %s sa %s\n", $file,
scalar localtime($write_secs);

Kung mas gusto mo ang isang bagay na mas madaling mabasa, gamitin ang File::stat module (bahagi ng standard
pamamahagi sa bersyon 5.004 at mas bago):

# error checking ang natitira bilang ehersisyo para sa mambabasa.
gamitin ang File::stat;
gamitin ang Oras::localtime;
aking $date_string = ctime(stat($file)->mtime);
i-print ang "file $file na-update sa $date_string\n";

Ang POSIX::strftime() diskarte ay may pakinabang ng pagiging, sa teorya, independyente sa
kasalukuyang lokal. Tingnan ang perllocale para sa mga detalye.

Gaano do I itakda a mga file timestamp in perl?
Ginagamit mo ang utime() function na nakadokumento sa "utime" sa perlfunc. Bilang halimbawa, narito
isang maliit na programa na kinokopya ang mga oras ng pagbasa at pagsulat mula sa unang argumento nito hanggang sa lahat ng
iba sa kanila.

kung (@ARGV < 2) {
mamatay "paggamit: ctimes timestamp_file other_files ...\n";
}
aking $timestamp = shift;
my($atime, $mtime) = (stat($timestamp))[8,9];
utime $atime, $mtime, @ARGV;

Ang pag-check ng error ay, gaya ng dati, naiwan bilang isang ehersisyo para sa mambabasa.

Ang perldoc para sa utime ay mayroon ding isang halimbawa na may parehong epekto bilang hawakan(1) sa mga file
na na umiral.

Ang ilang mga file system ay may limitadong kakayahang mag-imbak ng mga oras sa isang file sa inaasahan
antas ng katumpakan. Halimbawa, ang FAT at HPFS filesystem ay hindi makakagawa ng mga petsa sa
mga file na may mas pinong granularity kaysa sa dalawang segundo. Ito ay isang limitasyon ng mga filesystem,
hindi ng utime().

Gaano do I i-print sa mas marami pang kaysa isa file at minsan?
Upang ikonekta ang isang filehandle sa ilang output filehandles, maaari mong gamitin ang IO::Tee o
Tie::FileHandle::Multiplex modules.

Kung kailangan mo lang gawin ito nang isang beses, maaari kang mag-print nang isa-isa sa bawat filehandle.

para sa aking $fh ($fh1, $fh2, $fh3) { print $fh "whatever\n" }

Gaano maaari I basahin in an buo file lahat at minsan?
Ang karaniwang diskarte ng Perl para sa pagproseso ng lahat ng mga linya sa isang file ay gawin ito sa isang linya sa
isang oras:

buksan ang aking $input, '<', $file o mamatay "hindi mabuksan ang $file: $!";
habang (<$input>) {
chomp;
# gumawa ng isang bagay sa $_
}
isara ang $input o mamatay "hindi maisara ang $file: $!";

Ito ay lubhang mas mahusay kaysa sa pagbabasa ng buong file sa memorya bilang isang array
ng mga linya at pagkatapos ay pinoproseso ito ng isang elemento sa isang pagkakataon, na madalas--kung hindi halos
palaging--maling diskarte. Sa tuwing may makikita kang gawin ito:

aking @linya = ;

Dapat mong pag-isipan nang matagal at mabuti kung bakit kailangan mong i-load ang lahat nang sabay-sabay. Hindi lang
isang nasusukat na solusyon.

Kung "mmmap" mo ang file gamit ang File::Map module mula sa CPAN, halos mai-load mo ang
buong file sa isang string nang hindi aktwal na iniimbak ito sa memorya:

gamitin ang File::Map qw(map_file);

map_file ang aking $string, $filename;

Kapag na-map, maaari mong ituring ang $string gaya ng gagawin mo sa anumang iba pang string. Dahil wala ka
kinakailangang i-load ang data, ang mmap-ing ay maaaring napakabilis at maaaring hindi mapataas ang iyong
bakas ng memorya.

Maaari mo ring makitang mas masaya na gamitin ang karaniwang Tie::File module, o ang DB_File
$DB_RECNO bindings ng module, na nagbibigay-daan sa iyong itali ang isang array sa isang file upang ma-access ang
aktwal na ina-access ng isang elemento ng array ang kaukulang linya sa file.

Kung gusto mong i-load ang buong file, maaari mong gamitin ang Path::Tiny module para gawin ito sa isa
simple at mahusay na hakbang:

gamitin ang Path::Tiny;

my $all_of_it = path($filename)->slurp; # buong file sa scalar
my @all_lines = path($filename)->lines; # isang linya bawat elemento

O maaari mong basahin ang buong nilalaman ng file sa isang scalar tulad nito:

aking $var;
{
lokal na $/;
buksan ang aking $fh, '<', $file o mamatay "hindi mabuksan ang $file: $!";
$var = <$fh>;
}

Iyon ay pansamantalang i-undef ang iyong record separator, at awtomatikong isasara ang file sa
harangan ang labasan. Kung nakabukas na ang file, gamitin lang ito:

my $var = gawin { local $/; <$fh> };

Maaari ka ring gumamit ng isang naka-localize na @ARGV upang alisin ang "bukas":

my $var = do { local( @ARGV, $/ ) = $file; <> };

Para sa mga ordinaryong file maaari mo ring gamitin ang function na "read".

basahin( $fh, $var, -s $fh );

Sinusubukan ng ikatlong argumentong iyon ang laki ng byte ng data sa $fh filehandle at binabasa iyon
maraming byte sa buffer $var.

Gaano maaari I basahin in a file by mga talata?
Gamitin ang $/ variable (tingnan ang perlvar para sa mga detalye). Maaari mo itong itakda sa "" para alisin
mga walang laman na talata ("abc\n\n\n\ndef", halimbawa, ay itinuturing bilang dalawang talata at hindi
tatlo), o "\n\n" para tanggapin ang mga walang laman na talata.

Tandaan na ang isang blangkong linya ay dapat na walang mga blangko dito. Kaya ang "fred\n \nstuff\n\n" ay isa
talata, ngunit ang "fred\n\nstuff\n\n" ay dalawa.

Gaano maaari I basahin a solong katangian mula a file? mula sa ang keyboard?
Maaari mong gamitin ang builtin na function na "getc()" para sa karamihan ng mga filehandle, ngunit hindi ito (madaling) gagana.
sa isang terminal device. Para sa STDIN, gamitin ang Term::ReadKey module mula sa CPAN o gamitin ang
sample code sa "getc" sa perlfunc.

Kung sinusuportahan ng iyong system ang portable operating system programming interface (POSIX), ikaw
maaaring gamitin ang sumusunod na code, na mapapansin mong i-off din ang pagproseso ng echo.

#!/usr/bin/perl -w
gumamit ng mahigpit;
$| = 1;
para sa (1..4) {
i-print ang "gimme: ";
my $got = getone();
i-print ang "--> $got\n";
}
exit;

MAGSIMULA {
gumamit ng POSIX qw(:termios_h);

my ($term, $oterm, $echo, $noecho, $fd_stdin);

my $fd_stdin = fileno(STDIN);

$term = POSIX::Termios->new();
$term->getattr($fd_stdin);
$oterm = $term->getlflag();

$echo = ECHO | ECHOK | ICANON;
$noecho = $oterm & ~$echo;

sub cbreak {
$term->setlflag($noecho);
$term->setcc(VTIME, 1);
$term->setattr($fd_stdin, TCSANOW);
}

sub cooked {
$term->setlflag($oterm);
$term->setcc(VTIME, 0);
$term->setattr($fd_stdin, TCSANOW);
}

sub getone {
aking $key = '';
cbreak();
sysread(STDIN, $key, 1);
niluto();
ibalik ang $key;
}
}

WAKAS { niluto() }

Maaaring mas madaling gamitin ang Term::ReadKey module mula sa CPAN. Kasama rin sa mga kamakailang bersyon
suporta para sa mga non-portable system din.

gamitin ang Term::ReadKey;
buksan ang aking $tty, '<', '/dev/tty';
i-print ang "Gimme a char: ";
ReadMode "raw";
aking $key = ReadKey 0, $tty;
ReadMode "normal";
printf "\nSinabi mo %s, char number %03d\n",
$key, o $key;

Gaano maaari I sabihin kung mayroon a katangian naghihintay on a filehandle?
Ang pinakaunang bagay na dapat mong gawin ay tingnan ang pagkuha ng Term::ReadKey extension mula sa
CPAN. Tulad ng nabanggit namin kanina, mayroon na itong limitadong suporta para sa hindi portable (basahin: hindi
bukas na mga sistema, sarado, pagmamay-ari, hindi POSIX, hindi Unix, atbp.) mga sistema.

Dapat mo ring tingnan ang listahan ng Mga Madalas Itanong sa comp.unix.* para sa mga bagay
tulad nito: ang sagot ay mahalagang pareho. Ito ay napaka-system-dependent. Narito ang isa
solusyon na gumagana sa mga sistema ng BSD:

sub key_ready {
my($rin, $nfd);
vec($rin, fileno(STDIN), 1) = 1;
return $nfd = piliin($rin,undef,undef,0);
}

Kung gusto mong malaman kung ilang karakter ang naghihintay, nariyan din ang FIONREAD ioctl
tawag para tignan. Ang h2ph tool na kasama ng Perl na sinusubukang i-convert ang C kasama ang mga file
sa Perl code, na maaaring "kailangan" d. Nagtatapos ang FIONREAD na tinukoy bilang isang function sa
sys/ioctl.ph file:

nangangailangan ng 'sys/ioctl.ph';

$size = pack("L", 0);
ioctl(FH, FIONREAD(), $size) o mamatay na "Hindi matawagan ang ioctl: $!\n";
$size = unpack("L", $size);

If h2ph ay hindi na-install o hindi gumagana para sa iyo, maaari mo grep isama ang mga file sa pamamagitan ng kamay:

% grep FIONREAD /usr/include/* / *
/usr/include/asm/ioctls.h:#define FIONREAD 0x541B

O magsulat ng isang maliit na C program gamit ang editor ng mga kampeon:

% pusa > fionread.c
#isama
pangunahing() {
printf("%#08x\n", FIONREAD);
}
^D
% cc -o fionread fionread.c
% ./fionread
0x4004667f

At pagkatapos ay i-hard-code ito, na iniiwan ang pag-port bilang isang ehersisyo sa iyong kahalili.

$FIONREAD = 0x4004667f; # XXX: umaasa sa opsy

$size = pack("L", 0);
ioctl(FH, $FIONREAD, $size) o mamatay na "Hindi matawagan ang ioctl: $!\n";
$size = unpack("L", $size);

Ang FIONREAD ay nangangailangan ng filehandle na konektado sa isang stream, ibig sabihin, ang mga socket, pipe, at tty
gumagana ang mga device, ngunit hindi file.

Gaano do I do a "buntot -f" in perl?
Unang subukan

humingi($gw_fh, 0, 1);

Ang pahayag na "seek ($gw_fh, 0, 1)" ay hindi nagbabago sa kasalukuyang posisyon, ngunit ito ay malinaw
ang end-of-file na kundisyon sa hawakan, upang ang susunod na "<$gw_fh>" ay subukang muli si Perl
para magbasa ng isang bagay.

Kung hindi iyon gumana (umaasa ito sa mga tampok ng iyong pagpapatupad ng stdio), kailangan mo
mas katulad nito:

para kay (;;) {
para sa ($curpos = tell($gw_fh); <$gw_fh>; $curpos =tell($gw_fh)) {
# maghanap ng ilang bagay at ilagay ito sa mga file
}
#tulog sandali
humingi($gw_fh, $curpos, 0); # hanapin kung saan tayo napunta
}

Kung hindi pa rin ito gumana, tingnan ang "clearerr" na paraan mula sa IO::Handle, na nagre-reset
ang error at end-of-file states sa handle.

Mayroon ding File::Tail module mula sa CPAN.

Gaano do I dup() a filehandle in Perl?
Kung susuriin mo ang "bukas" sa perlfunc, makikita mo ang ilan sa mga paraan ng pagtawag bukas() dapat
gawin ang lansihin. Halimbawa:

buksan ang aking $log, '>>', '/foo/logfile';
buksan ang STDERR, '>&', $log;

O kahit na may literal na deskriptor ng numero:

aking $fd = $ENV{MHCONTEXTFD};
buksan ang $mhcontext, "<&=$fd"; # gaya ng fdopen(3S)

Tandaan na ang "<&STDIN" ay gumagawa ng isang kopya, ngunit ang "<&=STDIN" ay gumagawa ng isang alias. Ibig sabihin kung magsasara ka
isang naka-alyas na hawakan, ang lahat ng mga alias ay nagiging hindi naa-access. Ito ay hindi totoo sa isang kinopya.

Ang pagsuri ng error, gaya ng dati, ay iniwan bilang isang ehersisyo para sa mambabasa.

Gaano do I malapit a file deskriptor by numero?
Kung, sa ilang kadahilanan, mayroon kang isang file descriptor sa halip na isang filehandle (marahil ay ginamit mo
"POSIX::open"), maaari mong gamitin ang function na "close()" mula sa POSIX module:

gumamit ng POSIX ();

POSIX::close( $fd );

Ito ay bihirang kinakailangan, dahil ang Perl na "close()" function ay gagamitin para sa mga bagay
na binuksan mismo ni Perl, kahit na ito ay isang dup ng isang numeric descriptor tulad ng sa "MHCONTEXT"
sa itaas. Ngunit kung kailangan mo talaga, maaari mong gawin ito:

nangangailangan ng 'sys/syscall.ph';
my $rc = syscall(SYS_close(), $fd + 0); # dapat pilitin ang numero
mamatay "hindi ma-sysclose ang $fd: $!" maliban kung $rc == -1;

O, gamitin lang ang fdopen(3S) na tampok ng "open()":

{
buksan ang aking $fh, "<&=$fd" o mamatay "Hindi mabuksan muli ang fd=$fd: $!";
malapit $fh;
}

Bakit hindi pwede I gamitin "C:\temp\foo" in DOS mga landas? Bakit hindi `C:\temp\foo.exe` gumagana?
Oops! Maglagay ka lang ng tab at isang formfeed sa filename na iyon! Tandaan na sa loob
double quoted strings ("like\this"), ang backslash ay isang escape character. Ang buong listahan
sa mga ito ay nasa "Quote and Quote-like Operators" sa perlop. Hindi nakakagulat, wala ka
isang file na tinatawag na "c:(tab)emp(formfeed)oo" o "c:(tab)emp(formfeed)oo.exe" sa iyong legacy na DOS
filesystem.

Alinman sa iisang-quote ang iyong mga string, o (mas mabuti) gumamit ng mga forward slash. Dahil ang lahat ng DOS at
Ang mga bersyon ng Windows dahil ang isang bagay tulad ng MS-DOS 2.0 o higit pa ay tinatrato ang "/" at "\" nang pareho
sa isang landas, maaari mo ring gamitin ang isa na hindi sumasalungat sa Perl--o ang POSIX shell,
ANSI C at C++, awk, Tcl, Java, o Python, para lang magbanggit ng ilan. POSIX path ay higit pa
portable din.

Bakit hindi glob("*.*") makuha lahat ang mga file?
Dahil kahit sa mga non-Unix port, ang glob function ng Perl ay sumusunod sa karaniwang Unix globbing
semantika. Kakailanganin mo ang "glob("*")" para makuha ang lahat ng (hindi nakatago) na file. Ginagawa nitong glob()
portable kahit sa mga legacy system. Maaaring kasama sa iyong port ang mga proprietary globbing function bilang
mabuti. Suriin ang dokumentasyon nito para sa mga detalye.

Bakit ang Perl pabayaan me alisin Basahin lamang mga file? Bakit ang "-ako" clobber protektado mga file? Hindi ba ito
a kulisap in Perl?
Ito ay detalyado at maingat na inilarawan sa file-dir-perms artikulo sa "Far
Higit Pa Sa Gusto Mong Malaman" na koleksyon sa
<http://www.cpan.org/misc/olddoc/FMTEYEWTK.tgz>.

Ang executive summary: alamin kung paano gumagana ang iyong filesystem. Ang mga pahintulot sa isang file ay nagsasabi kung ano
maaaring mangyari sa data sa file na iyon. Ang mga pahintulot sa isang direktoryo ay nagsasabi kung ano ang maaaring mangyari
sa listahan ng mga file sa direktoryong iyon. Kung tatanggalin mo ang isang file, inaalis mo ang pangalan nito
mula sa direktoryo (kaya ang operasyon ay nakasalalay sa mga pahintulot ng direktoryo, hindi ng
ang file). Kung susubukan mong magsulat sa file, ang mga pahintulot ng file ay namamahala kung
pinapayagan ka.

Gaano do I piliin a walang pili linya mula a file?
Kapos sa paglo-load ng file sa isang database o paunang pag-index ng mga linya sa file, mayroon
ilang bagay na maaari mong gawin.

Narito ang isang reservoir-sampling algorithm mula sa Camel Book:

srand;
rand($.) < 1 && ($line = $_) habang <>;

Ito ay may malaking kalamangan sa espasyo kaysa sa pagbabasa ng buong file. Makakakita ka ng a
patunay ng pamamaraang ito sa Ang Sining of computer Programming, Volume 2, Seksyon 3.4.2, ni
Donald E. Knuth.

Maaari mong gamitin ang File::Random na module na nagbibigay ng function para sa algorithm na iyon:

gamitin ang File::Random qw/random_line/;
aking $line = random_line($filename);

Ang isa pang paraan ay ang paggamit ng Tie::File module, na tinatrato ang buong file bilang array.
I-access lamang ang isang random na elemento ng array.

Bakit do I makuha kakaiba mga puwang kailan I i-print an ayos of mga linya?
(kontribusyon ni brian d foy)

Kung nakakakita ka ng mga puwang sa pagitan ng mga elemento ng iyong array kapag nag-print ka ng array, ikaw
ay marahil interpolating ang array sa double quotes:

my @animals = qw(camel llama alpaca vicuna);
print "ang mga hayop ay: @hayop\n";

Ito ay ang double quotes, hindi ang "print", ang paggawa nito. Sa tuwing mag-interpolate ka ng array
isang dobleng konteksto ng quote, sinasali ni Perl ang mga elemento na may mga puwang (o anuman ang nasa $", which
ay isang puwang bilang default):

Ang mga hayop ay: camel llama alpaca vicuna

Ito ay iba kaysa sa pag-print ng array nang walang interpolation:

my @animals = qw(camel llama alpaca vicuna);
print "ang mga hayop ay: ", @hayop, "\n";

Ngayon ang output ay walang mga puwang sa pagitan ng mga elemento dahil ang mga elemento ng
Ang @animals ay naging bahagi lamang ng listahan na "i-print":

Ang mga hayop ay: camelllamaalpacavicuna

Maaari mong mapansin ito kapag ang bawat isa sa mga elemento ng @array ay nagtatapos sa isang bagong linya. Inaasahan mo
upang mag-print ng isang elemento sa bawat linya, ngunit mapansin na ang bawat linya pagkatapos ng una ay naka-indent:

ito ay isang linya
ito ay isa pang linya
ito ang pangatlong linya

Ang sobrang espasyo ay nagmumula sa interpolation ng array. Kung ayaw mong ilagay
anumang bagay sa pagitan ng iyong mga elemento ng array, huwag gamitin ang array sa double quotes. Maaari kang magpadala
ito upang i-print nang wala ang mga ito:

i-print ang @mga linya;

Gaano do I tawirin a direktoryo puno?
(kontribusyon ni brian d foy)

Ang File::Find module, na kasama ng Perl, ay ginagawa ang lahat ng hirap sa pagtawid sa a
istraktura ng direktoryo. Kasama nito si Perl. Tawagan mo lang ang subroutine na "hanapin" na may a
callback subroutine at ang mga direktoryo na gusto mong daanan:

gamitin ang File::Find;

find( \&wanted, @directories );

sub wanted {
# buong landas sa $File::Find::name
# filename lang sa $_
... gawin mo lahat ng gusto mong gawin...
}

Ang File::Find::Closures, na maaari mong i-download mula sa CPAN, ay nagbibigay ng maraming handa nang gamitin
mga subroutine na magagamit mo sa File::Find.

Ang File::Finder, na maaari mong i-download mula sa CPAN, ay makakatulong sa iyong gawin ang callback
subroutine gamit ang isang bagay na mas malapit sa syntax ng "find" command-line utility:

gamitin ang File::Find;
gamitin ang File::Finder;

my $deep_dirs = File::Finder->depth->type('d')->ls->exec('rmdir','{}');

find( $deep_dirs->as_options, @places );

Ang File::Find::Rule module, na maaari mong i-download mula sa CPAN, ay may katulad na interface,
ngunit para sa iyo din ang paglalakbay:

gamitin ang File::Find::Rule;

my @files = File::Find::Rule->file()
->pangalan( '*.pm' )
->in( @INC );

Gaano do I alisin a direktoryo puno?
(kontribusyon ni brian d foy)

Kung mayroon kang isang walang laman na direktoryo, maaari mong gamitin ang built-in na "rmdir" ng Perl. Kung ang direktoryo ay
hindi walang laman (kaya, walang mga file o subdirectory), kailangan mong alisan ng laman ito mismo (maraming
trabaho) o gumamit ng modyul para tulungan ka.

Ang module ng File::Path, na kasama ng Perl, ay may "remove_tree" na maaaring mag-ingat sa
lahat ng hirap para sa iyo:

gamitin ang File::Path qw(remove_tree);

remove_tree( @directories );

Ang File::Path module ay mayroon ding legacy na interface sa mas lumang "rmtree" subroutine.

Gaano do I kopyahin an buo direktoryo?
(na iniambag ni Shlomi Fish)

Upang gawin ang katumbas ng "cp -R" (ibig sabihin, kopyahin ang isang buong puno ng direktoryo nang pabalik-balik) sa
portable Perl, kakailanganin mong magsulat ng isang bagay sa iyong sarili o maghanap ng magandang CPAN module
gaya ng File::Copy::Recursive.

AUTHOR AT COPYRIGHT


Copyright (c) 1997-2010 Tom Christiansen, Nathan Torkington, at iba pang mga may-akda gaya ng nabanggit.
Lahat ng karapatan ay nakareserba.

Ang dokumentasyong ito ay libre; maaari mo itong muling ipamahagi at/o baguhin ito sa ilalim ng parehong mga tuntunin
bilang Perl mismo.

Anuman ang pamamahagi nito, lahat ng mga halimbawa ng code dito ay nasa pampublikong domain. Ikaw ay
pinahihintulutan at hinihikayat na gamitin ang code na ito at anumang mga derivatives nito sa sarili mong mga programa
para masaya o para kumita ayon sa nakikita mong akma. Isang simpleng komento sa code na nagbibigay ng kredito sa
Ang FAQ ay magiging magalang ngunit hindi kinakailangan.

Gamitin ang perlfaq5 online gamit ang mga serbisyo ng onworks.net


Mga Libreng Server at Workstation

Mag-download ng Windows at Linux apps

Linux command

Ad