Ini adalah perintah perlfaq5 yang dapat dijalankan di penyedia hosting gratis OnWorks menggunakan salah satu dari beberapa stasiun kerja online gratis kami seperti Ubuntu Online, Fedora Online, emulator online Windows atau emulator online MAC OS
PROGRAM:
NAMA
perlfaq5 - File dan Format
VERSION
versi 5.021009
DESKRIPSI
Bagian ini membahas masalah I/O dan "f": penanganan file, pembilasan, format, dan
catatan kaki.
Seterpercayaapakah Olymp Trade? Kesimpulan do I flush / unbuffer an keluaran menangani file? Mengapa harus I do ini?
(disumbangkan oleh brian d foy)
Anda mungkin ingin membaca "Suffering From Buffering" karya Mark Jason Dominus di
<http://perl.plover.com/FAQs/Buffering.html>.
Perl biasanya buffer output sehingga tidak membuat panggilan sistem untuk setiap bit output. Oleh
menghemat output, itu membuat panggilan sistem yang lebih murah. Misalnya, di bagian kecil ini
kode, Anda ingin mencetak titik ke layar untuk setiap baris yang Anda proses untuk menonton
kemajuan program Anda. Alih-alih melihat titik untuk setiap baris, Perl menyangga output
dan Anda harus menunggu lama sebelum Anda melihat deretan 50 titik sekaligus:
# tunggu lama, lalu deretan titik sekaligus
sementara( <> ) {
cetak ".";
print "\n" kecuali ++$count % 50;
#... operasi pemrosesan jalur yang mahal
}
Untuk menyiasatinya, Anda harus menghapus pegangan file keluaran, dalam hal ini, "STDOUT".
Anda dapat mengatur variabel khusus $| ke nilai sebenarnya (mnemonic: membuat pegangan file Anda
"panas sekali"):
$|++;
# titik segera ditampilkan
sementara( <> ) {
cetak ".";
print "\n" kecuali ++$count % 50;
#... operasi pemrosesan jalur yang mahal
}
$| adalah salah satu variabel khusus per-filehandle, jadi setiap filehandle memiliki salinannya sendiri
dari nilainya. Jika Anda ingin menggabungkan keluaran standar dan kesalahan standar misalnya, Anda
harus unbuffer masing-masing (walaupun STDERR mungkin unbuffered secara default):
{
$previous_default saya = pilih(STDOUT); # simpan default sebelumnya
$|++; # STDOUT autoflush
pilih(STDERR);
$|++; # autoflush STDERR, pastinya
pilih($previous_default); # kembalikan default sebelumnya
}
# sekarang harus bergantian. dan +
sementara( 1 ) {
tidur 1;
cetak STDOUT ".";
cetak STDERR "+";
print STDOUT "\n" kecuali ++$count % 25;
}
Selain $| variabel khusus, Anda dapat menggunakan "binmode" untuk memberikan filehandle Anda ":unix"
lapisan, yang tidak buffer:
binmode(STDOUT, ":unix");
sementara( 1 ) {
tidur 1;
cetak ".";
print "\n" kecuali ++$count % 50;
}
Untuk informasi lebih lanjut tentang lapisan keluaran, lihat entri untuk "binmode" dan buka di perlfunc,
dan dokumentasi modul PerlIO.
Jika Anda menggunakan IO::Handle atau salah satu subkelasnya, Anda dapat memanggil metode "autoflush"
untuk mengubah pengaturan pegangan file:
gunakan IO::Menangani;
buka my( $io_fh ), ">", "output.txt";
$io_fh->pembilasan otomatis(1);
Objek IO::Handle juga memiliki metode "flush". Anda dapat menyiram buffer kapan saja Anda
inginkan tanpa buffering otomatis
$io_fh->flush;
Seterpercayaapakah Olymp Trade? Kesimpulan do I perubahan, menghapus, or menyisipkan a line in a file, or menambahkan untuk itu awal of a mengajukan?
(disumbangkan oleh brian d foy)
Ide dasar menyisipkan, mengubah, atau menghapus baris dari file teks melibatkan
membaca dan mencetak file ke titik Anda ingin membuat perubahan, membuat perubahan,
kemudian membaca dan mencetak sisa file. Perl tidak menyediakan akses acak ke
baris (terutama karena pemisah input record, $/, dapat diubah), meskipun modul seperti
sebagai Tie::File dapat memalsukannya.
Program Perl untuk melakukan tugas-tugas ini mengambil bentuk dasar membuka file, mencetaknya
baris, lalu tutup file:
buka $in saya, '<', $file or die "Tidak dapat membaca file lama: $!";
open my $out, '>', "$file.new" or die "Tidak dapat menulis file baru: $!";
sementara( <$dalam> ) {
cetak $keluar $_;
}
tutup $keluar;
Dalam formulir dasar itu, tambahkan bagian yang perlu Anda sisipkan, ubah, atau hapus garis.
Untuk menambahkan baris ke awal, cetak baris tersebut sebelum Anda memasukkan loop yang dicetak
garis-garis yang ada.
buka $in saya, '<', $file or die "Tidak dapat membaca file lama: $!";
open my $out, '>', "$file.new" or die "Tidak dapat menulis file baru: $!";
print $out "# Tambahkan baris ini ke atas\n"; # <--- INILAH KEAJAIBANNYA
sementara( <$dalam> ) {
cetak $keluar $_;
}
tutup $keluar;
Untuk mengubah baris yang ada, masukkan kode untuk mengubah baris di dalam loop "sementara". Di
kasus ini, kode menemukan semua versi huruf kecil dari "Perl" dan huruf besar mereka. Itu
terjadi untuk setiap baris, jadi pastikan Anda melakukannya di setiap baris!
buka $in saya, '<', $file or die "Tidak dapat membaca file lama: $!";
open my $out, '>', "$file.new" or die "Tidak dapat menulis file baru: $!";
print $out "# Tambahkan baris ini ke atas\n";
sementara( <$dalam> ) {
s/\b(Perl)\b/Perl/g;
cetak $keluar $_;
}
tutup $keluar;
Untuk mengubah hanya baris tertentu, nomor baris input, $., berguna. Pertama baca dan
cetak baris hingga yang ingin Anda ubah. Selanjutnya, baca satu baris yang Anda inginkan
mengubah, mengubahnya, dan mencetaknya. Setelah itu, baca sisa baris dan cetak itu:
while( <$in> ) { # cetak baris sebelum perubahan
cetak $keluar $_;
terakhir jika $. == 4; # nomor baris sebelum berubah
}
$baris saya = <$dalam>;
$baris =~ s/\b(perl)\b/Perl/g;
cetak $keluar $baris;
while( <$in> ) { # cetak sisa baris
cetak $keluar $_;
}
Untuk melewati garis, gunakan kontrol perulangan. "Berikutnya" dalam contoh ini melewatkan baris komentar,
dan "terakhir" menghentikan semua pemrosesan setelah menemukan "__END__" atau "__DATA__".
sementara( <$dalam> ) {
selanjutnya jika /^\s+#/; # lewati baris komentar
terakhir jika /^__(END|DATA)__$/; # berhenti di akhir penanda kode
cetak $keluar $_;
}
Lakukan hal yang sama untuk menghapus baris tertentu dengan menggunakan "berikutnya" untuk melewati baris
Anda tidak ingin muncul di output. Contoh ini melewatkan setiap baris kelima:
sementara( <$dalam> ) {
berikutnya kecuali $. % 5;
cetak $keluar $_;
}
Jika, untuk beberapa alasan aneh, Anda benar-benar ingin melihat seluruh file sekaligus daripada
memproses baris demi baris, Anda dapat menyeruputnya (selama Anda dapat memasukkan semuanya)
Penyimpanan!):
buka $in saya, '<', $file or die "Tidak dapat membaca file lama: $!"
open my $out, '>', "$file.new" or die "Tidak dapat menulis file baru: $!";
$konten saya = lakukan { lokal $/; <$dalam> }; # menyeruput!
# lakukan keajaibanmu di sini
cetak $keluar $konten;
Modul seperti Path::Tiny dan Tie::File juga dapat membantu. Jika Anda bisa, bagaimanapun,
hindari membaca seluruh file sekaligus. Perl tidak akan mengembalikan memori itu ke operasi
sistem sampai proses selesai.
Anda juga dapat menggunakan Perl one-liners untuk memodifikasi file di tempat. Berikut ini mengubah semua
'Fred' ke 'Barney' di di File.txt, menimpa file dengan konten baru. Dengan
sakelar "-p", Perl membungkus loop "sementara" di sekitar kode yang Anda tentukan dengan "-e", dan "-i"
mengaktifkan pengeditan di tempat. Baris saat ini ada di $_. Dengan "-p", Perl secara otomatis mencetak
nilai $_ di akhir loop. Lihat perlrun untuk lebih jelasnya.
perl -pi -e 's/Fred/Barney/' inFile.txt
Untuk membuat cadangan "inFile.txt", berikan "-i" ekstensi file untuk ditambahkan:
perl -pi.bak -e 's/Fred/Barney/' inFile.txt
Untuk mengubah hanya baris kelima, Anda dapat menambahkan pemeriksaan pengujian $., nomor baris input, lalu
hanya melakukan operasi ketika tes lulus:
perl -pi -e 's/Fred/Barney/ jika $. == 5' di File.txt
Untuk menambahkan baris sebelum baris tertentu, Anda dapat menambahkan baris (atau baris!) sebelum Perl mencetak $_:
perl -pi -e 'print "Letakkan sebelum baris ketiga\n" jika $. == 3' di File.txt
Anda bahkan dapat menambahkan baris ke awal file, karena baris saat ini dicetak di
akhir lingkaran:
perl -pi -e 'print "Letakkan sebelum baris pertama\n" jika $. == 1' di File.txt
Untuk menyisipkan baris setelah satu baris sudah ada di file, gunakan sakelar "-n". Ini seperti "-p"
kecuali bahwa itu tidak mencetak $_ di akhir loop, jadi Anda harus melakukannya sendiri.
Dalam hal ini, cetak $_ terlebih dahulu, lalu cetak baris yang ingin Anda tambahkan.
perl -ni -e 'cetak; print "Letakkan setelah baris kelima\n" jika $. == 5' di File.txt
Untuk menghapus garis, hanya cetak garis yang Anda inginkan.
perl -ni -e 'print if /d/' inFile.txt
Seterpercayaapakah Olymp Trade? Kesimpulan do I menghitung itu jumlah of baris in a mengajukan?
(disumbangkan oleh brian d foy)
Secara konseptual, cara termudah untuk menghitung baris dalam file adalah dengan membacanya dan
menghitungnya:
$hitungan saya = 0;
while( <$fh> ) { $hitung++; }
Anda tidak benar-benar harus menghitungnya sendiri, karena Perl sudah melakukannya dengan
$. variabel, yang merupakan nomor baris saat ini dari filehandle terakhir yang dibaca:
1 while( <$fh> );
$hitungan saya = $.;
Jika Anda ingin menggunakan $., Anda dapat menguranginya menjadi satu baris sederhana, seperti salah satu dari ini:
% perl -lne '} print $.; {' file
% perl -lne 'END { print $. berkas }'
Itu bisa agak tidak efisien. Jika mereka tidak cukup cepat untuk Anda, Anda mungkin saja
baca potongan data dan hitung jumlah baris baru:
$garis saya = 0;
open my($fh), '<:raw', $filename or die "Tidak dapat membuka $filename: $!";
while( sysread $fh, $buffer, 4096 ) {
$baris += ( $buffer =~ tr/\n// );
}
tutup $fj;
Namun, itu tidak berfungsi jika akhir baris bukan baris baru. Anda mungkin mengubah itu
"tr///" ke "s///" sehingga Anda dapat menghitung berapa kali pemisah catatan input, $/,
muncul:
$garis saya = 0;
open my($fh), '<:raw', $filename or die "Tidak dapat membuka $filename: $!";
while( sysread $fh, $buffer, 4096 ) {
$baris += ( $buffer =~ s|$/||g; );
}
tutup $fj;
Jika Anda tidak keberatan keluar, perintah "wc" biasanya yang tercepat, bahkan dengan
overhead interproses ekstra. Pastikan Anda memiliki nama file yang tidak ternoda:
#!perl-T
$ENV{PATH} = tidak pasti;
$baris saya;
if( $namafile =~ /^([0-9a-z_.]+)\z/ ) {
$baris = `/usr/bin/wc -aku $1`
chomp $baris;
}
Seterpercayaapakah Olymp Trade? Kesimpulan do I hapus itu terakhir N baris dari a mengajukan?
(disumbangkan oleh brian d foy)
Solusi konseptual termudah adalah menghitung baris dalam file kemudian mulai dari
awal dan cetak jumlah baris (dikurangi N terakhir) ke file baru.
Paling sering, pertanyaan sebenarnya adalah bagaimana Anda dapat menghapus N baris terakhir tanpa membuat lebih banyak
dari satu melewati file, atau bagaimana melakukannya tanpa banyak menyalin. Konsep yang mudah adalah
kenyataan pahit ketika Anda mungkin memiliki jutaan baris dalam file Anda.
Salah satu triknya adalah menggunakan File::ReadBackwards, yang dimulai di akhir file. Modul itu
menyediakan objek yang membungkus filehandle asli untuk memudahkan Anda bergerak
berkas. Setelah Anda sampai di tempat yang Anda butuhkan, Anda bisa mendapatkan filehandle yang sebenarnya dan bekerja
dengan itu seperti biasa. Dalam hal ini, Anda mendapatkan posisi file di akhir baris terakhir Anda
ingin menyimpan dan memotong file ke titik itu:
gunakan File::ReadBackwards;
$namafile saya = 'test.txt';
$Lines_to_truncate saya = 2;
my $bw = File::ReadBackwards->new( $filename )
atau die "Tidak dapat membaca mundur di [$nama file]: $!";
$lines_from_end saya = 0;
sampai( $bw->eof atau $lines_from_end == $Lines_to_truncate ) {
print "Dapatkan: ", $bw->readline;
$baris_dari_end++;
}
truncate( $namafile, $bw->beri tahu );
Modul File::ReadBackwards juga memiliki keuntungan mengatur catatan input
pemisah ke ekspresi reguler.
Anda juga dapat menggunakan modul Tie::File yang memungkinkan Anda mengakses garis melalui ikatan
Himpunan. Anda dapat menggunakan operasi array normal untuk memodifikasi file Anda, termasuk mengatur yang terakhir
indeks dan menggunakan "sambatan".
Seterpercayaapakah Olymp Trade? Kesimpulan bisa I menggunakan Perl's "-SAYA" Option dari dalam a program?
"-i" menetapkan nilai variabel $^I Perl, yang selanjutnya mempengaruhi perilaku "<>";
lihat perlrun untuk lebih jelasnya. Dengan memodifikasi variabel yang sesuai secara langsung, Anda bisa mendapatkan
perilaku yang sama dalam program yang lebih besar. Sebagai contoh:
# ...
{
local($^I, @ARGV) = ('.orig', glob("*.c"));
sementara (<>) {
jika ($. == 1) {
print "Baris ini akan muncul di bagian atas setiap file\n";
}
s/\b(p)earl\b/${1}erl/i; # Koreksi kesalahan ketik, pertahankan kasus
cetak;
tutup ARGV jika eof; # Setel ulang $.
}
}
# $^I dan @ARGV kembali ke nilai lama mereka di sini
Blok ini memodifikasi semua file ".c" di direktori saat ini, meninggalkan cadangan dari
data asli dari setiap file dalam file ".c.orig" baru.
Seterpercayaapakah Olymp Trade? Kesimpulan bisa I salinan a mengajukan?
(disumbangkan oleh brian d foy)
Gunakan modul File::Copy. Muncul dengan Perl dan dapat melakukan salinan yang benar di seluruh sistem file,
dan melakukan keajaibannya dengan cara portabel.
gunakan Berkas::Salin;
copy( $original, $new_copy ) or die "Penyalinan gagal: $!";
Jika Anda tidak dapat menggunakan File::Copy, Anda harus melakukannya sendiri: buka file asli,
buka file tujuan, lalu cetak ke file tujuan saat Anda membaca aslinya.
Anda juga harus ingat untuk menyalin izin, pemilik, dan grup ke file baru.
Seterpercayaapakah Olymp Trade? Kesimpulan do I membuat a sementara fillet nama?
Jika Anda tidak perlu mengetahui nama file, Anda dapat menggunakan "open()" dengan "undef" sebagai gantinya
dari nama file. Di Perl 5.8 atau lebih baru, fungsi "buka ()" membuat anonim
berkas sementara:
buka $tmp, '+>', undef or die $!;
Jika tidak, Anda dapat menggunakan modul File::Temp.
gunakan File::Temp qw/ tempfile tempdir /;
my $dir = tempdir( PEMBERSIHAN => 1 );
($fh, $namafile) = tempfile( DIR => $dir );
# atau jika Anda tidak perlu tahu nama filenya
my $fh = tempfile( DIR => $dir );
File::Temp telah menjadi modul standar sejak Perl 5.6.1. Jika Anda tidak memiliki yang modern
cukup Perl diinstal, gunakan metode kelas "new_tmpfile" dari modul IO::File untuk mendapatkan
filehandle dibuka untuk membaca dan menulis. Gunakan jika Anda tidak perlu mengetahui filenya
Nama:
gunakan IO::File;
$fh saya = IO::File->new_tmpfile()
atau die "Tidak dapat membuat file sementara baru: $!";
Jika Anda berkomitmen untuk membuat file sementara dengan tangan, gunakan ID proses dan/atau
nilai waktu saat ini. Jika Anda perlu memiliki banyak file sementara dalam satu proses, gunakan a
menangkal:
MULAI {
gunakan Fcntl;
gunakan File::Spec;
my $temp_dir = File::Spec->tmpdir();
my $file_base = sprintf "%d-%d-0000", $$, waktu;
my $base_name = File::Spec->catfile($temp_dir, $file_base);
subtemp_file {
$fj saya;
$hitungan saya = 0;
sampai( didefinisikan(fileno($fh)) || $count++ > 100 ) {
$base_name =~ s/-(\d+)$/"-" . (1 + $1)/e;
# O_EXCL diperlukan untuk alasan keamanan.
sysopen $fh, $nama_dasar, O_WRONLY|O_EXCL|O_CREAT;
}
if( didefinisikan fileno($fh) ) {
kembali ($fh, $nama_dasar);
}
else {
kembali ();
}
}
}
Seterpercayaapakah Olymp Trade? Kesimpulan bisa I memanipulasi panjang-rekaman tetap file?
Cara yang paling efisien adalah menggunakan mengemas() dan membongkar(). Ini lebih cepat daripada menggunakan substr()
ketika mengambil banyak, banyak string. Ini lebih lambat hanya untuk beberapa.
Berikut adalah contoh potongan kode untuk dipecah dan disatukan kembali beberapa format tetap
baris input, dalam hal ini dari output normal, gaya Berkeley ps:
# contoh baris masukan:
# 15158 p5 T 0:00 perl /home/tchrist/scripts/sekarang-apa
my $PS_T = 'A6 A4 A7 A5 A*';
buka $ps saya, '-|', 'ps';
cetak skalar <$ps>;
my @fields = qw( pid tt stat perintah waktu );
sementara (<$ps>) {
%proses saya;
@proses{@fields} = membongkar($PS_T, $_);
untuk $field saya ( @fields ) {
print "$bidang: <$proses{$bidang}>\n";
}
print 'line=', pack($PS_T, @process{@fields} ), "\n";
}
Kami telah menggunakan irisan hash untuk menangani bidang setiap baris dengan mudah. Menyimpan
kunci dalam array memudahkan untuk mengoperasikannya sebagai grup atau mengulangnya dengan "untuk".
Itu juga menghindari polusi program dengan variabel global dan menggunakan referensi simbolis.
Seterpercayaapakah Olymp Trade? Kesimpulan bisa I membuat a pegangan file lokal untuk a subrutin? Seterpercayaapakah Olymp Trade? Kesimpulan do I lulus pegangan file antara
subrutin? Seterpercayaapakah Olymp Trade? Kesimpulan do I membuat an susunan of menangani file?
Pada perl5.6, Buka() menangani file dan direktori secara otomatis sebagai referensi jika Anda meneruskannya
variabel skalar yang tidak diinisialisasi. Anda kemudian dapat meneruskan referensi ini seperti yang lainnya
skalar, dan menggunakannya di tempat pegangan bernama.
buka $fh, $file_name saya;
buka $fh lokal, $file_name;
print $fh "Halo Dunia!\n";
proses_file( $fh );
Jika Anda suka, Anda dapat menyimpan filehandle ini dalam array atau hash. Jika Anda mengaksesnya
langsung, itu bukan skalar sederhana dan Anda perlu memberi "cetak" sedikit bantuan dengan menempatkan
referensi filehandle dalam kurung. Perl hanya bisa mengetahuinya sendiri ketika
referensi filehandle adalah skalar sederhana.
saya @fhs = ( $fh1, $fh2, $fh3 );
untuk( $i = 0; $i <= $#fhs; $i++ ) {
print {$fhs[$i]} "hanya jawaban Perl yang lain, \n";
}
Sebelum perl5.6, Anda harus berurusan dengan berbagai idiom typeglob yang mungkin Anda lihat di versi lama
kode.
buka FILE, "> $namafile";
proses_typeglob( *FILE );
proses_referensi( \*FILE );
sub process_typeglob { lokal *FH = shift; cetak FH "Typeglob!" }
subproses_referensi { local $fh = shift; print $fh "Referensi!" }
Jika Anda ingin membuat banyak pegangan anonim, Anda harus memeriksa Simbol atau
IO::Menangani modul.
Seterpercayaapakah Olymp Trade? Kesimpulan bisa I menggunakan a pegangan file secara tidak langsung?
Sebuah filehandle tidak langsung adalah penggunaan sesuatu selain simbol di tempat yang a
penanganan file diharapkan. Berikut adalah cara untuk mendapatkan penanganan file tidak langsung:
$fj = BEBERAPA_FH; # bareword ketat-subs bermusuhan
$fh = "SOME_FH"; # ketat-ref bermusuhan; paket yang sama saja
$fj = *SOME_FH; #typeglob
$fh = \*SOME_FH; # ref ke typeglob (berkat-mampu)
$fh = *SOME_FH{IO}; # diberkati IO :: Menangani dari *SOME_FH typeglob
Atau, Anda dapat menggunakan metode "baru" dari salah satu modul IO::* untuk membuat anonim
filehandle dan simpan dalam variabel skalar.
gunakan IO::Menangani; #5.004 atau lebih tinggi
my $fh = IO::Handle->new();
Kemudian gunakan salah satu dari itu seperti yang Anda lakukan pada filehandle normal. Di mana pun Perl mengharapkan
filehandle, sebuah filehandle tidak langsung dapat digunakan sebagai gantinya. Filehandle tidak langsung hanyalah sebuah
variabel skalar yang berisi filehandle. Fungsi seperti "mencetak", "membuka", "mencari", atau
" " operator berlian akan menerima filehandle bernama atau variabel skalar
berisi satu:
($jika, $ofh, $efh) = (*STDIN, *STDOUT, *STDERR);
print $ofh "Ketik: ";
$dapatkan saya = <$ifh>
print $efh "Apa itu: $dapat";
Jika Anda meneruskan filehandle ke suatu fungsi, Anda dapat menulis fungsi tersebut dengan dua cara:
sub terima_fh {
$fh saya = shift;
print $fh "Mengirim ke filehandle tidak langsung\n";
}
Atau dapat melokalkan typeglob dan menggunakan filehandle secara langsung:
sub terima_fh {
lokal *FH = shift;
print FH "Mengirim ke filehandle lokal\n";
}
Kedua gaya bekerja dengan baik objek atau typeglobs dari filehandle nyata. (Mereka mungkin juga
bekerja dengan string dalam beberapa keadaan, tetapi ini berisiko.)
terima_fh(*STDOUT);
accept_fh($menangani);
Dalam contoh di atas, kami menetapkan filehandle ke variabel skalar sebelum menggunakannya.
Itu karena hanya variabel skalar sederhana, bukan ekspresi atau subskrip hash atau
array, dapat digunakan dengan built-in seperti "print", "printf", atau operator berlian. Menggunakan
sesuatu selain variabel skalar sederhana sebagai filehandle adalah ilegal dan bahkan tidak akan
menyusun:
@fd saya = (*STDIN, *STDOUT, *STDERR);
print $fd[1] "Ketik: "; # SALAH
$punya saya = <$fd[0]> # SALAH
print $fd[2] "Apa itu: $dapat"; # SALAH
Dengan "print" dan "printf", Anda menyiasatinya dengan menggunakan blok dan ekspresi di mana
anda akan menempatkan filehandle:
print { $fd[1] } "hal-hal lucu\n";
printf { $fd[1] } "Kasihan yang miskin %x.\n", 3_735_928_559;
# Kasihan daging sapi mati yang malang.
Blok itu adalah blok yang tepat seperti yang lain, sehingga Anda dapat menempatkan kode yang lebih rumit di sana.
Ini mengirimkan pesan ke salah satu dari dua tempat:
$ok saya = -x "/bin/kucing";
cetak { $ok ? $fd[1] : $fd[2] } "status kucing $ok\n";
print { $fd[ 1+ ($ok || 0) ] } "cat stat $ok\n";
Pendekatan memperlakukan "print" dan "printf" seperti panggilan metode objek ini tidak berfungsi untuk
operator berlian. Itu karena itu adalah operator nyata, bukan hanya fungsi dengan a
argumen tanpa koma. Dengan asumsi Anda telah menyimpan typeglobs dalam struktur Anda seperti yang kami lakukan
di atas, Anda dapat menggunakan fungsi bawaan bernama "readline" untuk membaca catatan seperti halnya "<>"
melakukan. Mengingat inisialisasi yang ditunjukkan di atas untuk @fd, ini akan berhasil, tetapi hanya karena
garis baca() membutuhkan typeglob. Itu tidak berfungsi dengan objek atau string, yang mungkin a
bug yang belum kami perbaiki.
$dapat = readline($fd[0]);
Perlu dicatat bahwa kerapuhan penanganan file tidak langsung tidak terkait dengan apakah
mereka string, typeglobs, objek, atau apa pun. Ini sintaks dasarnya
operator. Memainkan permainan objek tidak membantu Anda sama sekali di sini.
Seterpercayaapakah Olymp Trade? Kesimpulan bisa I set up a footer format untuk be bekas dengan menulis()?
Tidak ada cara bawaan untuk melakukan ini, tetapi Perlform memiliki beberapa teknik untuk membuatnya
mungkin untuk hacker pemberani.
Seterpercayaapakah Olymp Trade? Kesimpulan bisa I menulis() ke a rangkaian?
(disumbangkan oleh brian d foy)
Jika Anda ingin "menulis" menjadi string, Anda hanya perlu filehandle ke string,
yang dapat dilakukan Perl sejak Perl 5.6:
buka FH, '>', \my $string;
tulis ( FH );
Karena Anda ingin menjadi programmer yang baik, Anda mungkin ingin menggunakan filehandle leksikal,
meskipun format dirancang untuk bekerja dengan filehandle bareword sejak default
nama format mengambil nama filehandle. Namun, Anda dapat mengontrol ini dengan beberapa Perl
variabel per-filehandle khusus: $^, yang menamai format halaman teratas, dan $~ yang
menunjukkan format garis. Anda harus mengubah filehandle default untuk mengatur variabel-variabel ini:
buka my($fh), '>', \my $string;
{ # setel variabel per-penanganan file
$old_fh saya = pilih( $fh );
$~ = 'HEWAN';
$^ = 'ANIMAL_TOP';
pilih( $lama_fh );
}
format HEWAN_TOP =
Nama Jenis ID
.
format HEWAN =
@## @<<<< @<<<<<<<<<<<<
$id, $tipe, $nama
.
Meskipun menulis dapat bekerja dengan variabel leksikal atau paket, variabel apa pun yang Anda gunakan memiliki
untuk ruang lingkup dalam format. Itu kemungkinan besar berarti Anda ingin melokalkan beberapa paket
variabel:
{
lokal( $id, $type, $nama ) = qw( 12 kucing Buster );
tulis( $fj );
}
cetak $string;
Ada juga beberapa trik yang bisa Anda mainkan dengan "formline" dan variabel akumulator
$^A, tetapi Anda kehilangan banyak nilai format karena "formline" tidak akan menangani paging dan
segera. Anda akhirnya mengimplementasikan ulang format saat Anda menggunakannya.
Seterpercayaapakah Olymp Trade? Kesimpulan bisa I Buka a pegangan file untuk a rangkaian?
(disumbangkan oleh Peter J. Holzer, [email dilindungi])
Sejak Perl 5.8.0, pegangan file yang merujuk ke string dapat dibuat dengan memanggil open dengan a
referensi ke string itu alih-alih nama file. Pegangan file ini kemudian dapat digunakan untuk
membaca dari atau menulis ke string:
open(my $fh, '>', \$string) or die "Tidak dapat membuka string untuk menulis";
print $fh "foo\n";
print $fh "bilah\n"; # $string sekarang berisi "foo\nbar\n"
open($fh saya, '<', \$string) or die "Tidak dapat membuka string untuk membaca";
$x saya = <$fh>; # $x sekarang berisi "foo\n"
Dengan versi Perl yang lebih lama, modul IO::String menyediakan fungsionalitas yang serupa.
Seterpercayaapakah Olymp Trade? Kesimpulan bisa I keluaran my nomor dengan koma ditambahkan?
(disumbangkan oleh brian d foy dan Benjamin Goldberg)
Anda dapat menggunakan Number::Format untuk memisahkan tempat dalam angka. Ini menangani informasi lokal
bagi Anda yang ingin memasukkan titik penuh sebagai gantinya (atau apa pun yang mereka inginkan
gunakan, sungguh).
Subrutin ini akan menambahkan koma ke nomor Anda:
subkomitif {
lokal $_ = shift;
1 sementara s/^([-+]?\d+)(\d{3})/$1,$2/;
kembali $_;
}
Regex dari Benjamin Goldberg ini akan menambahkan koma ke angka:
s/(^[-+]?\d+?(?=(?>(?:\d{3})+)(?!\d))|\G\d{3}(?=\d) )/$1,/g;
Lebih mudah untuk melihat dengan komentar:
S/(
^[-+]? # awal angka.
\d+? # digit pertama sebelum koma pertama
(?= # diikuti oleh, (tetapi tidak termasuk dalam kecocokan):
(?>(?:\d{3})+) # beberapa kelipatan positif dari tiga angka.
(?!\d) # kelipatan *tepat*, bukan x * 3 +1 atau apa pun.
)
| # atau:
\G\d{3} # setelah grup terakhir, dapatkan tiga digit
(?=\d) # tetapi mereka harus memiliki lebih banyak angka setelahnya.
)/$1,/xg;
Seterpercayaapakah Olymp Trade? Kesimpulan bisa I menterjemahkan tilde (~) in a nama file?
Gunakan operator <> ("glob()"), didokumentasikan dalam perlfunc. Versi Perl yang lebih lama dari 5.6
mengharuskan Anda menginstal shell yang groks tildes. Versi Perl yang lebih baru memiliki
fitur ini ada di dalamnya. Modul File::KGlob (tersedia dari CPAN) memberikan lebih banyak portabel
fungsionalitas bola.
Dalam Perl, Anda dapat menggunakan ini secara langsung:
$namafile =~ s{
^ ~ # temukan tilde utama
( # simpan ini dalam $1
[^/] # karakter bukan garis miring
*# diulang 0 kali atau lebih (0 berarti saya)
)
}{
$1
? (dapatkanpwnam($1))[7]
: ( $ENV{HOME} || $ENV{LOGDIR} )
}mantan;
Seterpercayaapakah Olymp Trade? Kesimpulan bagaimana ketika I Buka a fillet Baca tulis it lap it di luar?
Karena Anda menggunakan sesuatu seperti ini, yang memotong file kemudian memberi Anda membaca-
akses tulis:
buka $fh saya, '+>', '/path/name'; # SALAH (hampir selalu)
Ups. Anda sebaiknya menggunakan ini, yang akan gagal jika file tidak ada:
buka $fh, '+<', '/path/name' saya; # terbuka untuk pembaruan
Menggunakan ">" selalu clobbers atau menciptakan. Menggunakan "<" juga tidak pernah berhasil. "+" tidak berubah
ini.
Berikut adalah contoh dari berbagai jenis file yang terbuka. Mereka yang menggunakan "sysopen" semuanya berasumsi bahwa
Anda telah menarik konstanta dari Fcntl:
gunakan Fcntl;
Untuk membuka file untuk dibaca:
buka $fh, '<', $path or die $!;
buka $fh, $path, O_RDONLY saya atau mati $!;
Untuk membuka file untuk menulis, buat file baru jika diperlukan atau potong file lama:
buka $fh, '>', $path or die $!;
sysbuka $fh, $path, O_WRONLY|O_TRUNC|O_CREAT saya atau mati $!;
buka $fh, $path, O_WRONLY|O_TRUNC|O_CREAT, 0666 atau die $!;
Untuk membuka file untuk menulis, buat file baru, file tidak boleh ada:
sysopen $fh, $path, O_WRONLY|O_EXCL|O_CREAT saya atau die $!;
buka $fh, $path, O_WRONLY|O_EXCL|O_CREAT, 0666 atau die $!;
Untuk membuka file untuk ditambahkan, buat jika perlu:
buka $fh saya, '>>' $path or die $!;
sysbuka $fh, $path, O_WRONLY|O_APPEND|O_CREAT saya atau mati $!;
buka $fh, $path, O_WRONLY|O_APPEND|O_CREAT, 0666 atau die $!;
Untuk membuka file untuk ditambahkan, file harus ada:
sysopen $fh, $path, O_WRONLY|O_APPEND saya atau die $!;
Untuk membuka file untuk pembaruan, file harus ada:
buka $fh, '+<', $path or die $!;
sysopen $fh, $path, O_RDWR saya atau mati $!;
Untuk membuka file untuk pembaruan, buat file jika perlu:
buka $fh, $path, O_RDWR|O_CREAT saya atau die $!;
buka $fh, $path, O_RDWR|O_CREAT, 0666 atau mati $!;
Untuk membuka file untuk pembaruan, file tidak boleh ada:
buka $fh, $path, O_RDWR|O_EXCL|O_CREAT saya atau die $!;
buka $fh, $path, O_RDWR|O_EXCL|O_CREAT, 0666 atau die $!;
Untuk membuka file tanpa memblokir, buat jika perlu:
sysbuka $fh saya, '/foo/somefile', O_WRONLY|O_NDELAY|O_CREAT
atau mati "tidak dapat membuka /foo/somefile: $!":
Berhati-hatilah bahwa baik pembuatan maupun penghapusan file tidak dijamin bersifat atomik
operasi melalui NFS. Artinya, dua proses mungkin berhasil membuat atau memutuskan tautan
berkas yang sama! Oleh karena itu O_EXCL tidak seeksklusif yang Anda harapkan.
Lihat juga perlopentut.
Mengapa do I kadang-kadang mendapatkan an "Argumen daftar terlalu panjang" ketika I menggunakan <*>?
Operator "<>" melakukan operasi globbing (lihat di atas). Di versi Perl sebelumnya
dari v5.6.0, internal gumpal() garpu operator csh(1) untuk melakukan ekspansi glob yang sebenarnya,
tetapi csh tidak dapat menangani lebih dari 127 item sehingga memberikan pesan kesalahan "Daftar argumen juga
long". Orang yang menginstal tcsh sebagai csh tidak akan mengalami masalah ini, tetapi pengguna mereka mungkin
terkejut karenanya.
Untuk menyiasatinya, tingkatkan ke Perl v5.6.0 atau lebih baru, lakukan glob sendiri dengan
bacadir() dan pola, atau gunakan modul seperti File::Glob, yang tidak menggunakan shell untuk
melakukan globbing.
Seterpercayaapakah Olymp Trade? Kesimpulan bisa I Buka a fillet dengan a terkemuka ">" or tertinggal kosong?
(disumbangkan oleh Brian McCauley)
Bentuk dua argumen khusus dari Perl's Buka() fungsi mengabaikan trailing blank di
nama file dan menyimpulkan mode dari karakter utama tertentu (atau tanda "|"). Di
versi lama Perl ini adalah satu-satunya versi Buka() dan jadi itu lazim di masa lalu
kode dan buku.
Kecuali Anda memiliki alasan tertentu untuk menggunakan formulir dua argumen, Anda harus menggunakan tiga-
bentuk argumen dari Buka() yang tidak memperlakukan karakter apa pun dalam nama file sebagai spesial.
buka $fh saya, "<", " file "; # nama file adalah "file"
buka $fh saya, ">", ">file"; # nama file adalah ">file"
Seterpercayaapakah Olymp Trade? Kesimpulan bisa I andal mengubah nama a mengajukan?
Jika sistem operasi Anda mendukung yang tepat mv(1) utilitas atau fungsi yang setara,
ini bekerja:
rename($old, $new) or system("mv", $old, $new);
Mungkin lebih portabel untuk menggunakan modul File::Copy sebagai gantinya. Anda cukup menyalin ke yang baru
file ke nama baru (memeriksa nilai pengembalian), lalu hapus yang lama. Ini tidak benar-benar
sama secara semantik sebagai "rename()", yang mempertahankan meta-informasi seperti izin,
cap waktu, info inode, dll.
Seterpercayaapakah Olymp Trade? Kesimpulan bisa I mengunci a mengajukan?
bawaan Perl kawanan() fungsi (lihat perlfunc untuk detailnya) akan memanggil kawanan(2) jika itu
ada, fcntl(2) jika tidak (pada Perl versi 5.004 dan yang lebih baru), dan kunci(3) jika tidak
dari dua panggilan sistem sebelumnya ada. Pada beberapa sistem, bahkan mungkin menggunakan yang berbeda
bentuk penguncian asli. Berikut adalah beberapa gotcha dengan Perl's kawanan():
1. Menghasilkan kesalahan fatal jika tidak ada dari tiga panggilan sistem (atau yang setara)
ada
2. kunci(3) tidak menyediakan penguncian bersama, dan mengharuskan pegangan file terbuka untuk
menulis (atau menambahkan, atau membaca/menulis).
3. Beberapa versi dari kawanan() tidak dapat mengunci file melalui jaringan (misalnya pada sistem file NFS),
jadi Anda harus memaksa penggunaan fcntl(2) ketika Anda membangun Perl. Tapi bahkan ini
meragukan di terbaik. Lihat entri kawanan perlfunc dan INSTALL file di sumbernya
distribusi untuk informasi tentang membangun Perl untuk melakukan ini.
Dua semantik kawanan yang berpotensi tidak jelas tetapi tradisional adalah bahwa ia menunggu
tanpa batas sampai kunci diberikan, dan kuncinya adalah hanya laporan. Seperti
kunci diskresioner lebih fleksibel, tetapi menawarkan lebih sedikit jaminan. Ini berarti bahwa
file dikunci dengan kawanan() dapat dimodifikasi oleh program yang tidak juga menggunakan kawanan().
Mobil yang berhenti karena lampu merah saling cocok, tetapi tidak dengan mobil yang
jangan berhenti karena lampu merah. Lihat halaman manual perlport, spesifik port Anda
dokumentasi, atau halaman manual khusus sistem Anda untuk detailnya. Sebaiknya asumsikan
perilaku tradisional jika Anda sedang menulis program portabel. (Jika tidak, Anda harus
seperti biasa merasa sangat bebas untuk menulis untuk keistimewaan sistem Anda sendiri (terkadang
disebut "fitur"). Kepatuhan terhadap masalah portabilitas seharusnya tidak menjadi masalah
cara Anda menyelesaikan pekerjaan.)
Untuk informasi lebih lanjut tentang penguncian file, lihat juga "Penguncian File" di perlopentut jika Anda
memilikinya (baru untuk 5.6).
Mengapa tidak bisa I hanya buka (FH, ">file.lock")?
Sedikit kode yang umum JANGAN UNTUK GUNAKAN Apakah ini:
tidur(3) while -e 'file.lock'; # JANGAN GUNAKAN
buka $lock saya, '>', 'file.lock'; #KODE RUSAK INI
Ini adalah kondisi balapan klasik: Anda mengambil dua langkah untuk melakukan sesuatu yang harus dilakukan dalam
satu. Itu sebabnya perangkat keras komputer menyediakan instruksi pengujian dan pengaturan atom. Secara teori,
ini "seharusnya" bekerja:
sysbuka $fh saya, "file.lock", O_WRONLY|O_EXCL|O_CREAT
atau die "tidak dapat membuka file.lock: $!";
kecuali sayangnya, pembuatan file (dan penghapusan) tidak atomik melalui NFS, jadi ini tidak akan
bekerja (setidaknya, tidak setiap saat) melalui internet. Berbagai skema yang melibatkan tautan() telah
disarankan, tetapi ini cenderung melibatkan sibuk-menunggu, yang juga kurang diinginkan.
I masih tidak mendapatkan penguncian. I hanya ingin untuk kenaikan itu jumlah in itu file. Seterpercayaapakah Olymp Trade? Kesimpulan bisa I do ini?
Tidak adakah yang pernah memberitahu Anda bahwa counter hit halaman web tidak berguna? Mereka tidak menghitung angka
hits, mereka membuang-buang waktu, dan mereka hanya berfungsi untuk mengelus kesombongan penulis. Dia
lebih baik untuk memilih nomor acak; mereka lebih realistis.
Bagaimanapun, inilah yang dapat Anda lakukan jika Anda tidak dapat menahan diri.
gunakan Fcntl qw(:DEFAULT :flock);
sysopen my $fh, "numfile", O_RDWR|O_CREAT atau die "tidak dapat membuka numfile: $!";
kawanan $fh, LOCK_EX atau die "tidak bisa kawanan numfile: $!";
$num saya = <$fh> || 0;
seek $fh, 0, 0 or die "tidak dapat memundurkan numfile: $!";
truncate $fh, 0 or die "tidak dapat memotong numfile: $!";
(cetak $fh $num+1, "\n") atau die "tidak dapat menulis numfile: $!";
close $fh or die "tidak dapat menutup numfile: $!";
Inilah penghitung klik halaman web yang jauh lebih baik:
$hits = int( (waktu() - 850_000_000) / baris(1_000) );
Jika hitungannya tidak membuat teman Anda terkesan, maka kodenya mungkin. :-)
Semua I ingin untuk do is menambahkan a kecil jumlah of teks untuk itu akhir of a file. Do I masih memiliki untuk menggunakan
mengunci?
Jika Anda menggunakan sistem yang mengimplementasikan "flock" dengan benar dan Anda menggunakan contoh yang ditambahkan
kode dari "perldoc -f kawanan" semuanya akan baik-baik saja bahkan jika OS yang Anda gunakan tidak
menerapkan mode penambahan dengan benar (jika sistem seperti itu ada). Jadi, jika Anda senang membatasi
diri Anda ke OS yang menerapkan "flock" (dan itu tidak terlalu membatasi) kemudian
itulah yang harus Anda lakukan.
Jika Anda tahu Anda hanya akan menggunakan sistem yang menerapkan penambahan dengan benar
(yaitu bukan Win32) maka Anda dapat menghilangkan "seek" dari kode di jawaban sebelumnya.
Jika Anda tahu Anda hanya menulis kode untuk dijalankan pada OS dan sistem file yang menerapkannya
tambahkan mode dengan benar (sistem file lokal pada Unix modern misalnya), dan Anda tetap
file dalam mode buffer-blok dan Anda menulis kurang dari satu output buffer-penuh di antara masing-masing
pembilasan buffer manual maka setiap bufferload hampir dijamin akan ditulis ke
akhir file dalam satu potongan tanpa bercampur dengan output orang lain.
Anda juga dapat menggunakan fungsi "syswrite" yang hanya merupakan pembungkus di sekitar sistem Anda
menulis(2) panggilan sistem.
Masih ada kemungkinan teoretis kecil bahwa sinyal akan mengganggu level sistem
operasi "tulis ()" sebelum selesai. Ada juga kemungkinan bahwa beberapa STDIO
implementasi dapat memanggil beberapa level sistem "tulis ()" bahkan jika buffer kosong untuk
Mulailah. Mungkin ada beberapa sistem di mana probabilitas ini dikurangi menjadi nol, dan ini adalah
bukan masalah saat menggunakan ":perlio" alih-alih STDIO sistem Anda.
Seterpercayaapakah Olymp Trade? Kesimpulan do I acak memperbarui a biner mengajukan?
Jika Anda hanya mencoba menambal biner, dalam banyak kasus sesuatu yang sederhana seperti ini berfungsi:
perl -i -pe 's{window manager}{window mangler}g' /usr/bin/emacs
Namun, jika Anda memiliki catatan berukuran tetap, maka Anda dapat melakukan sesuatu yang lebih seperti ini:
$RECSIZE saya = 220; # ukuran catatan, dalam byte
$recno saya = 37; # catatan mana yang akan diperbarui
open my $fh, '+<', 'somewhere' or die "tidak dapat memperbarui di suatu tempat: $!";
cari $fh, $recno * $RECSIZE, 0;
read $fh, $record, $RECSIZE == $RECSIZE or die "tidak dapat membaca record $recno: $!";
# simpan rekamannya
cari $fh, -$RECSIZE, 1;
cetak $fh $rekaman;
tutup $fj;
Penguncian dan pemeriksaan kesalahan dibiarkan sebagai latihan untuk pembaca. Jangan lupakan mereka atau
Anda akan sangat menyesal.
Seterpercayaapakah Olymp Trade? Kesimpulan do I mendapatkan a file timestamp in perl?
Jika Anda ingin mendapatkan kembali waktu saat file terakhir kali dibaca, ditulis, atau disimpan
meta-data (pemilik, dll) berubah, Anda menggunakan -A, -M, atau -C operasi pengujian file sebagai
didokumentasikan dalam perlfunc. Ini mengambil usia file (diukur terhadap awal
waktu program Anda) dalam hari sebagai angka floating point. Beberapa platform mungkin tidak memiliki semuanya
dari waktu-waktu ini. Lihat perlport untuk detailnya. Untuk mengambil waktu "mentah" dalam hitungan detik sejak
zaman, Anda akan memanggil fungsi stat, lalu gunakan "localtime()", "gmtime()", atau
"POSIX::strftime()" untuk mengubahnya menjadi bentuk yang dapat dibaca manusia.
Ini sebuah contoh:
$write_secs saya = (stat($file))[9];
printf "file %s diperbarui pada %s\n", $file,
skalar waktu lokal($write_secs);
Jika Anda lebih suka sesuatu yang lebih mudah dibaca, gunakan modul File::stat (bagian dari standar
distribusi dalam versi 5.004 dan yang lebih baru):
# pemeriksaan kesalahan kiri sebagai latihan untuk pembaca.
gunakan File::stat;
gunakan Waktu::waktu setempat;
$date_string saya = ctime(stat($file)->mtime);
print "file $file diperbarui pada $date_string\n";
POSIX::strftime() pendekatan memiliki manfaat karena, secara teori, independen dari
lokal saat ini. Lihat perlllocale untuk detailnya.
Seterpercayaapakah Olymp Trade? Kesimpulan do I set a file timestamp in perl?
Anda menggunakan waktu() fungsi didokumentasikan dalam "utime" di perlfunc. Sebagai contoh, berikut ini
program kecil yang menyalin waktu baca dan tulis dari argumen pertama ke semua
sisanya.
jika (@ARGV < 2) {
die "penggunaan: cptimes timestamp_file other_files ...\n";
}
$timestamp saya = shift;
my($waktu, $mtime) = (stat($timestamp))[8,9];
waktu $waktu, $waktu, @ARGV;
Pemeriksaan kesalahan, seperti biasa, dibiarkan sebagai latihan bagi pembaca.
Perldoc untuk utime juga memiliki contoh yang memiliki efek yang sama seperti menyentuh(1) pada file
bahwa sudah ada.
Sistem file tertentu memiliki kemampuan terbatas untuk menyimpan waktu pada file pada waktu yang diharapkan
tingkat presisi. Misalnya, sistem file FAT dan HPFS tidak dapat membuat tanggal pada
file dengan perincian yang lebih baik dari dua detik. Ini adalah batasan dari sistem file,
bukan dari waktu().
Seterpercayaapakah Olymp Trade? Kesimpulan do I mencetak untuk lebih dari satu fillet at sekali?
Untuk menghubungkan satu filehandle ke beberapa output filehandle, Anda dapat menggunakan IO::Tee atau
Tie::FileHandle::Modul multipleks.
Jika Anda hanya perlu melakukan ini sekali, Anda dapat mencetak satu per satu ke setiap pegangan file.
untuk $fh ($fh1, $fh2, $fh3) { print $fh "whatever\n" }
Seterpercayaapakah Olymp Trade? Kesimpulan bisa I Baca baca in an seluruh fillet semua at sekali?
Pendekatan Perl biasa untuk memproses semua baris dalam file adalah melakukannya satu baris di
sebuah waktu:
buka $input saya, '<', $file or die "tidak dapat membuka $file: $!";
sementara (<$input>) {
mengunyah;
# lakukan sesuatu dengan $_
}
close $input or die "tidak dapat menutup $file: $!";
Ini jauh lebih efisien daripada membaca seluruh file ke dalam memori sebagai array
baris dan kemudian memprosesnya satu elemen pada satu waktu, yang sering--jika tidak hampir
selalu--pendekatan yang salah. Setiap kali Anda melihat seseorang melakukan ini:
@lines saya = ;
Anda harus berpikir panjang dan keras tentang mengapa Anda membutuhkan semuanya dimuat sekaligus. Hanya saja tidak
solusi yang terukur.
Jika Anda "mmap" file dengan modul File::Map dari CPAN, Anda dapat memuat secara virtual
seluruh file menjadi string tanpa benar-benar menyimpannya di memori:
gunakan File::Peta qw(file_peta);
map_file $string saya, $filename;
Setelah dipetakan, Anda dapat memperlakukan $string seperti halnya string lainnya. Karena kamu tidak
harus memuat data, mmap-ing bisa sangat cepat dan mungkin tidak menambah
jejak memori.
Anda mungkin juga merasa lebih menyenangkan menggunakan modul Tie::File standar, atau DB_File
$DB_RECNO binding modul, yang memungkinkan Anda untuk mengikat array ke file sehingga mengakses
elemen array sebenarnya mengakses baris yang sesuai dalam file.
Jika Anda ingin memuat seluruh file, Anda dapat menggunakan modul Path::Tiny untuk melakukannya dalam satu
langkah sederhana dan efisien:
gunakan Path::Tiny;
my $all_of_it = path($filename)->slurp; # seluruh file dalam skalar
@all_lines saya = path($filename)->lines; # satu baris per elemen
Atau Anda dapat membaca seluruh isi file menjadi skalar seperti ini:
$var saya;
{
lokal $/;
buka $fh, '<', $file or die "tidak dapat membuka $file: $!";
$var = <$fh>;
}
Itu untuk sementara membatalkan pemisah catatan Anda, dan secara otomatis akan menutup file di
blok keluar. Jika file sudah terbuka, gunakan saja ini:
my $var = do { lokal $/; <$fj> };
Anda juga dapat menggunakan @ARGV yang dilokalkan untuk menghilangkan "terbuka":
my $var = do { local( @ARGV, $/ ) = $file; <> };
Untuk file biasa Anda juga dapat menggunakan fungsi "baca".
baca( $fh, $var, -s $fh );
Argumen ketiga itu menguji ukuran byte data pada filehandle $fh dan membaca bahwa
banyak byte ke dalam buffer $var.
Seterpercayaapakah Olymp Trade? Kesimpulan bisa I Baca baca in a fillet by paragraf?
Gunakan variabel $/ (lihat perlvar untuk detailnya). Anda dapat mengaturnya ke "" untuk menghilangkan
paragraf kosong ("abc\n\n\n\ndef", misalnya, diperlakukan sebagai dua paragraf dan tidak
tiga), atau "\n\n" untuk menerima paragraf kosong.
Perhatikan bahwa baris kosong tidak boleh kosong. Jadi "fred\n \nstuff\n\n" adalah satu
paragraf, tetapi "fred\n\nstuff\n\n" adalah dua.
Seterpercayaapakah Olymp Trade? Kesimpulan bisa I Baca baca a tunggal karakter dari a mengajukan? Mulai dari itu papan ketik?
Anda dapat menggunakan fungsi "getc()" bawaan untuk sebagian besar penanganan file, tetapi tidak (dengan mudah) berfungsi
pada perangkat terminal. Untuk STDIN, gunakan modul Term::ReadKey dari CPAN atau gunakan
contoh kode di "getc" di perlfunc.
Jika sistem Anda mendukung antarmuka pemrograman sistem operasi portabel (POSIX), Anda
dapat menggunakan kode berikut, yang akan Anda perhatikan juga mematikan pemrosesan gema.
#!/usr/bin/Perl -w
gunakan ketat;
$| = 1;
untuk (1) {
print "beri aku:";
$dapatkan saya = getone();
print "--> $dapat\n";
}
exit;
MULAI {
gunakan POSIX qw(:termios_h);
saya ($istilah, $oterm, $echo, $noecho, $fd_stdin);
$fd_stdin saya = fileno(STDIN);
$term = POSIX::Termios->new();
$term->getattr($fd_stdin);
$oterm = $term->getlflag();
$gema = ECHO | ECHOK | ICANON;
$noecho = $oterm & ~$echo;
istirahat sub {
$term->setlflag($noecho);
$term->setcc(VTIME, 1);
$term->setattr($fd_stdin, TCSANOW);
}
sub dimasak {
$term->setlflag($oterm);
$term->setcc(VTIME, 0);
$term->setattr($fd_stdin, TCSANOW);
}
sub getone {
$kunci saya = '';
istirahat();
sysread(STDIN, $kunci, 1);
matang();
kembali $kunci;
}
}
SELESAI { dimasak() }
Modul Term::ReadKey dari CPAN mungkin lebih mudah digunakan. Versi terbaru termasuk juga
dukungan untuk sistem non-portabel juga.
gunakan Istilah::ReadKey;
buka $tty saya, '<', '/dev/tty';
print "Beri saya karakter: ";
ReadMode "mentah";
$kunci saya = ReadKey 0, $tty;
ReadMode "normal";
printf "\nAnda mengatakan %s, nomor karakter %03d\n",
$kunci, urutkan $kunci;
Seterpercayaapakah Olymp Trade? Kesimpulan bisa I mengatakan apakah disana a karakter menunggu on a menangani file?
Hal pertama yang harus Anda lakukan adalah mencari ekstensi Term::ReadKey dari
CPAN. Seperti yang kami sebutkan sebelumnya, sekarang bahkan memiliki dukungan terbatas untuk non-portabel (baca: tidak
sistem terbuka, tertutup, berpemilik, bukan POSIX, bukan Unix, dll.).
Anda juga harus memeriksa daftar Pertanyaan yang Sering Diajukan di comp.unix.* untuk hal-hal
seperti ini: jawabannya pada dasarnya sama. Ini sangat bergantung pada sistem. Ini dia
solusi yang bekerja pada sistem BSD:
sub kunci_siap {
saya($rin, $nfd);
vec($rin, fileno(STDIN), 1) = 1;
return $nfd = pilih($rin,undef,undef,0);
}
Jika Anda ingin mengetahui berapa banyak karakter yang menunggu, ada juga FIONREAD ioctl
panggilan untuk dilihat. Itu h2ph alat yang disertakan dengan Perl mencoba mengonversi C termasuk file
ke kode Perl, yang dapat "diperlukan" d. FIONREAD akhirnya didefinisikan sebagai fungsi dalam
sys/ioctl.ph File:
memerlukan 'sys/ioctl.ph';
$ukuran = paket("L", 0);
ioctl(FH, FIONREAD(), $size) or die "Tidak dapat memanggil ioctl: $!\n";
$ukuran = membongkar("L", $ukuran);
If h2ph tidak diinstal atau tidak berfungsi untuk Anda, Anda dapat grep termasuk file dengan tangan:
% grep FIONBACA /usr/sertakan/* / *
/usr/include/asm/ioctls.h:#define FIONREAD 0x541B
Atau tulis program C kecil menggunakan editor champions:
% kucing > fionread.c
#termasuk
utama() {
printf("%#08x\n", FIONREAD);
}
^D
% cc -o fionread fionread.c
% ./fionread
0x4004667f
Dan kemudian hard-code itu, meninggalkan porting sebagai latihan untuk penerus Anda.
$FIONREAD = 0x4004667f; # XXX: ketergantungan opsys
$ukuran = paket("L", 0);
ioctl(FH, $FIONREAD, $size) or die "Tidak dapat memanggil ioctl: $!\n";
$ukuran = membongkar("L", $ukuran);
FIONREAD membutuhkan filehandle yang terhubung ke aliran, artinya soket, pipa, dan tty
perangkat berfungsi, tetapi tidak file.
Seterpercayaapakah Olymp Trade? Kesimpulan do I do a "ekor -F" in perl?
Percobaan pertama
cari($gw_fh, 0, 1);
Pernyataan "seek($gw_fh, 0, 1)" tidak mengubah posisi saat ini, tetapi jelas
kondisi akhir file pada pegangan, sehingga "<$gw_fh>" berikutnya membuat Perl mencoba lagi
untuk membaca sesuatu.
Jika itu tidak berhasil (itu bergantung pada fitur implementasi stdio Anda), maka Anda perlu
sesuatu yang lebih seperti ini:
untuk (;;) {
for ($curpos = tell($gw_fh); <$gw_fh>; $curpos =tell($gw_fh)) {
# cari beberapa barang dan masukkan ke dalam file
}
#tidur sejenak
seek($gw_fh, $curpos, 0); # mencari ke tempat kita berada
}
Jika ini masih tidak berhasil, lihat metode "clearerr" dari IO::Handle, yang mengatur ulang
kesalahan dan status akhir file pada pegangan.
Ada juga File::Tail modul dari CPAN.
Seterpercayaapakah Olymp Trade? Kesimpulan do I menipu() a pegangan file in Perl?
Jika Anda mencentang "buka" di perlfunc, Anda akan melihat beberapa cara untuk menelepon Buka() harus
melakukan trik. Sebagai contoh:
buka $log saya, '>>', '/foo/logfile';
buka STDERR, '>&', $log;
Atau bahkan dengan deskriptor numerik literal:
$fd saya = $ENV{MHCONTEXTFD};
buka $mhcontext, "<&=$fd"; # menyukai fdopen(3-an)
Perhatikan bahwa "<&STDIN" membuat salinan, tetapi "<&=STDIN" membuat alias. Itu berarti jika Anda menutup
pegangan alias, semua alias menjadi tidak dapat diakses. Ini tidak benar dengan yang disalin.
Pemeriksaan kesalahan, seperti biasa, dibiarkan sebagai latihan bagi pembaca.
Seterpercayaapakah Olymp Trade? Kesimpulan do I menutup penjualan a fillet deskriptor by nomor?
Jika, karena alasan tertentu, Anda memiliki deskriptor file alih-alih pegangan file (mungkin Anda menggunakan
"POSIX::open"), Anda dapat menggunakan fungsi "close()" dari modul POSIX:
gunakan POSIX();
POSIX::tutup( $fd );
Ini jarang diperlukan, karena fungsi "close()" Perl akan digunakan untuk berbagai hal
bahwa Perl membuka dirinya sendiri, bahkan jika itu adalah tiruan dari deskriptor numerik seperti dengan "MHCONTEXT"
di atas. Tetapi jika Anda benar-benar harus melakukannya, Anda mungkin dapat melakukan ini:
memerlukan 'sys/syscall.ph';
$rc saya = syscall(SYS_close(), $fd + 0); # harus memaksa numerik
die "tidak dapat menutup $fd: $!" kecuali $rc == -1;
Atau, gunakan saja fdopen(3S) fitur "terbuka()":
{
buka $fh saya, "<&=$fd" or die "Tidak dapat membuka kembali fd=$fd: $!";
tutup $fj;
}
Mengapa tidak bisa I menggunakan "C:\temp\foo" in DOS jalan? Mengapa tidak `C:\temp\foo.exe` bekerja?
Ups! Anda cukup meletakkan tab dan formfeed ke dalam nama file itu! Ingat itu di dalam
string yang dikutip ganda ("seperti\ini"), garis miring terbalik adalah karakter pelarian. Daftar lengkapnya
di antaranya ada di "Operator Kutipan dan Seperti Kutipan" di perlop. Tidak mengherankan, Anda tidak memiliki
file bernama "c:(tab)emp(formfeed)oo" atau "c:(tab)emp(formfeed)oo.exe" di DOS lawas Anda
berkas sistem.
Baik kutip tunggal string Anda, atau (lebih disukai) gunakan garis miring. Karena semua DOS dan
Versi Windows sejak sesuatu seperti MS-DOS 2.0 atau lebih telah memperlakukan "/" dan "\" sama
di jalur, Anda mungkin juga menggunakan yang tidak berbenturan dengan Perl--atau POSIX Shell,
ANSI C dan C++, awk, Tcl, Java, atau Python, hanya untuk menyebutkan beberapa. Jalur POSIX lebih banyak
portabel juga.
Mengapa tidak gumpal("*.*") mendapatkan semua itu file?
Karena bahkan pada port non-Unix, fungsi glob Perl mengikuti standar Unix globbing
semantik. Anda memerlukan "glob("*")" untuk mendapatkan semua file (tidak tersembunyi). Ini membuat gumpal()
portabel bahkan untuk sistem lama. Port Anda mungkin menyertakan fungsi globbing eksklusif sebagai
dengan baik. Periksa dokumentasinya untuk detailnya.
Mengapa tidak Perl membiarkan me hapus read-only file? Mengapa tidak "-SAYA" mengkritik terlindung file? Bukankah ini
a kesalahan in Perl?
Hal ini dijelaskan secara rumit dan susah payah dalam file-dir-perm artikel di "Far
Koleksi More Than You Ever Wanted To Know" di
<http://www.cpan.org/misc/olddoc/FMTEYEWTK.tgz>.
Ringkasan eksekutif: pelajari cara kerja sistem file Anda. Izin pada file mengatakan apa
dapat terjadi pada data dalam file tersebut. Izin pada direktori mengatakan apa yang bisa terjadi
ke daftar file di direktori itu. Jika Anda menghapus file, Anda menghapus namanya
dari direktori (jadi operasinya tergantung pada izin direktori, bukan dari
berkas). Jika Anda mencoba menulis ke file, izin file mengatur apakah
Anda diperbolehkan.
Seterpercayaapakah Olymp Trade? Kesimpulan do I memilih a acak line dari a mengajukan?
Saat memuat file ke dalam database atau melakukan pra-pengindeksan baris dalam file, ada:
beberapa hal yang dapat Anda lakukan.
Berikut adalah algoritma pengambilan sampel reservoir dari Buku Unta:
pasir;
rand($.) < 1 && ($line = $_) while <>;
Ini memiliki keuntungan yang signifikan dalam ruang daripada membaca seluruh file. Anda dapat menemukan a
bukti metode ini di Seni of komputer Pemrograman, Volume 2, Bagian 3.4.2, oleh
Donald E.Knuth.
Anda dapat menggunakan modul File::Random yang menyediakan fungsi untuk algoritme itu:
gunakan File::Random qw/random_line/;
$baris saya = random_line($namafile);
Cara lain adalah dengan menggunakan modul Tie::File, yang memperlakukan seluruh file sebagai array.
Cukup akses elemen array acak.
Mengapa do I mendapatkan aneh spasi ketika I mencetak an susunan of garis?
(disumbangkan oleh brian d foy)
Jika Anda melihat spasi di antara elemen larik saat Anda mencetak larik, Anda
mungkin menginterpolasi array dalam tanda kutip ganda:
my @animals = qw(unta llama alpaca vicuna);
print "hewan adalah: @hewan\n";
Ini adalah tanda kutip ganda, bukan "cetak", yang melakukan ini. Setiap kali Anda menginterpolasi array di
konteks kutipan ganda, Perl menggabungkan elemen dengan spasi (atau apa pun yang ada di $", yang
adalah spasi secara default):
hewan adalah: unta llama alpaca vicuna
Ini berbeda dengan mencetak array tanpa interpolasi:
my @animals = qw(unta llama alpaca vicuna);
print "hewan adalah: ", @hewan, "\n";
Sekarang output tidak memiliki spasi di antara elemen karena elemen
@animals cukup menjadi bagian dari daftar untuk "mencetak":
hewan adalah: camelllamaalpacavicuna
Anda mungkin memperhatikan ini ketika setiap elemen @array diakhiri dengan baris baru. Anda mengharapkan
untuk mencetak satu elemen per baris, tetapi perhatikan bahwa setiap baris setelah yang pertama diindentasi:
ini adalah garis
ini adalah baris lain
ini baris ketiga
Ruang ekstra itu berasal dari interpolasi array. Jika Anda tidak ingin menempatkan
apa pun di antara elemen array Anda, jangan gunakan array dalam tanda kutip ganda. Anda dapat mengirim
untuk mencetak tanpa mereka:
cetak @baris;
Seterpercayaapakah Olymp Trade? Kesimpulan do I melintasi a direktori pohon?
(disumbangkan oleh brian d foy)
Modul File::Find, yang disertakan dengan Perl, melakukan semua kerja keras untuk melintasi
struktur direktori. Itu datang dengan Perl. Anda cukup memanggil subrutin "temukan" dengan a
subrutin panggilan balik dan direktori yang ingin Anda lintasi:
gunakan Berkas::Temukan;
temukan( \&dicari, @direktori );
sub ingin {
# path lengkap di $File::Find::name
# hanya nama file di $_
... lakukan apa pun yang ingin Anda lakukan ...
}
File::Find::Closures, yang dapat Anda unduh dari CPAN, menyediakan banyak file siap pakai
subrutin yang dapat Anda gunakan dengan File::Find.
File::Finder, yang dapat Anda unduh dari CPAN, dapat membantu Anda membuat panggilan balik
subrutin menggunakan sesuatu yang lebih dekat dengan sintaks utilitas baris perintah "find":
gunakan Berkas::Temukan;
gunakan File::Finder;
my $deep_dirs = File::Finder->depth->type('d')->ls->exec('rmdir','{}');
find( $deep_dirs->as_options, @places );
Modul File::Find::Rule, yang dapat Anda unduh dari CPAN, memiliki antarmuka yang serupa,
tetapi melakukan traversal untuk Anda juga:
gunakan File::Temukan::Aturan;
@file saya = File::Temukan::Aturan->file()
->nama( '*.pm' )
->di( @INC );
Seterpercayaapakah Olymp Trade? Kesimpulan do I hapus a direktori pohon?
(disumbangkan oleh brian d foy)
Jika Anda memiliki direktori kosong, Anda dapat menggunakan "rmdir" bawaan Perl. Jika direktori adalah
tidak kosong (jadi, tidak ada file atau subdirektori), Anda juga harus mengosongkannya sendiri (banyak
kerja) atau gunakan modul untuk membantu Anda.
Modul File::Path, yang disertakan dengan Perl, memiliki "remove_tree" yang dapat menangani
semua kerja keras untuk Anda:
gunakan File::Path qw(remove_tree);
hapus_pohon( @direktori );
Modul File::Path juga memiliki antarmuka lama ke subrutin "rmtree" yang lebih lama.
Seterpercayaapakah Olymp Trade? Kesimpulan do I salinan an seluruh direktori?
(disumbangkan oleh Ikan Shlomi)
Untuk melakukan yang setara dengan "cp -R" (yaitu menyalin seluruh pohon direktori secara rekursif) di
portabel Perl, Anda harus menulis sesuatu sendiri atau menemukan modul CPAN yang bagus
seperti File::Copy::Recursive.
PENULIS DAN HAK CIPTA
Hak Cipta (c) 1997-2010 Tom Christiansen, Nathan Torkington, dan penulis lain sebagaimana disebutkan.
Seluruh hak cipta.
Dokumentasi ini gratis; Anda dapat mendistribusikan ulang dan/atau memodifikasinya dengan persyaratan yang sama
sebagai Perl itu sendiri.
Terlepas dari distribusinya, semua contoh kode di sini berada dalam domain publik. Kamu adalah
diizinkan dan didorong untuk menggunakan kode ini dan turunannya dalam program Anda sendiri
untuk bersenang-senang atau untuk keuntungan sesuai keinginan Anda. Sebuah komentar sederhana dalam kode memberikan kredit untuk
FAQ akan sopan tetapi tidak diperlukan.
Gunakan perlfaq5 online menggunakan layanan onworks.net