Re: [問題] Perl讀檔 in Windows
試一下下面的 code,就可以看出 $/ ($INPUT_RECORD_SEPARATOR) 對於
換行的影響,也就是逐行讀入的差別所在。如果要讀的檔案不確定是用
何種換行符號,或是都存在各種換行符號,那麼可以考慮用 slurp mode
都讀進來後再處理。這個問題也很常見於寫一些網路應用程式,建議可以
參考 Net::Cmd 模組 getline() 函式。
my @buf = split(/\015?\012/, $buf, -1); ## break into lines
=================================================================
#!/usr/bin/perl
use strict;
use warnings;
my $data = "111\n222\n\r333\r\n444\r555";
my %IRS = (
ord("\n") => '\n',
ord("\r") => '\r',
);
sub get_chr_list {
my ($irs) = @_;
return join( "", map( $IRS{ ord($_) }, split( //, $irs ) ) );
}
sub load_file {
my ( $filename, $irs ) = @_;
$irs = defined($irs) ? $irs : "";
printf( "Current INPUT_RECORD_SEPARATOR = %s\n", get_chr_list($irs) );
do {
local $/ = $irs;
open( FH, "$filename" );
while (<FH>) {
chomp;
$_ =~ s/\n/\\n/g;
$_ =~ s/\r/\\r/g;
print "[$_]\n";
}
close(FH);
}
}
sub main {
open( FH, ">/tmp/test.txt" );
print FH $data;
close(FH);
printf( "Default INPUT_RECORD_SEPARATOR = %s\n", get_chr_list($/) );
load_file( "/tmp/test.txt", "\n" );
load_file( "/tmp/test.txt", "\n\r" );
load_file( "/tmp/test.txt", "\r\n" );
load_file( "/tmp/test.txt", undef ); # slurp
}
main;
※ 引述《abliou (把青春freeze)》之銘言:
: ※ 引述《StarTouching (撫星)》之銘言:
: : 找到原因了....
: : 首先要先知道
: : Windows的 command-line(亦即DOS) 按Enter時會送出\r\n
: : 但是在txt中, 只有\n (也許整個非Dos環境都是如此)
: : chomp預設只會篩掉\n,
: : 所以如果從STDIN讀入(DOS輸入),
: : 就會仍遺留下\r
: : 改$/ = "\r\n"
: : 可讓chomp篩掉\r\n
: : 但$/也影響到Perl讀取字串的斷點
: : 所以txt檔裡面只有\n 沒有\r,
: : 那Perl就找不到斷點,
: : 應該要把$/改回"\n"
: : 結論: 在Windows 需要DOS輸入時, 才需要改 $/
: : 不過這狀況其實不常用在實際應用,
: : 多半在練習或debug才會用,
: : 但正是因為如此, 初學者才更容易遇到這個問題而不知解決方法
: 看到這邊就想到大約兩年前的討論串 不過往上爬文已經找不到了
: 有一種方法叫做slurp 作法就是把$/設為undef
: 這樣在讀檔就會略過換行符號 把整個檔的內容放到字串中
: 這種方法用在網頁的tag處理很有用
: 因為在擷取網頁資料時都是在擷取兩個tag中間的資訊
: 所以無形中換行符號就變成一種問題
: (當然在常規表示式中會有解決方案)
: Perl中很多預設變數 在更改都會有用處跟用意 不過也要注意後面的影響
: ps.我承認我蠻菜的 不過目前我用過的perl 都還沒碰過原po碰到的問題
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.114.64.130
推
03/21 21:34, , 1F
03/21 21:34, 1F
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 5 之 5 篇):
Perl 近期熱門文章
PTT數位生活區 即時熱門文章