كيف تقرأ السطر من خلال السطر ملف CR-only مع Perl؟
-
26-09-2019 - |
سؤال
أحاول قراءة ملف يحتوي على CR فقط كحل محدد. أنا أستخدم Mac OS X و Perl V.5.8.8. يجب أن يعمل هذا البرنامج النصي على كل منصة ، لكل نوع من محددات الخط (CR ، LF ، CRLF).
الكود الحالي الخاص بي هو ما يلي:
open(FILE, "test.txt");
while($record = <FILE>){
print $record;
}
close(TEST);
هذا حاليا طباعة السطر الأخير فقط (أو الأسوأ). ما الذي يجري؟ بملء ، أود عدم تحويل الملف. هل هو ممكن؟
المحلول
يمكنك تعيين المحدد باستخدام المتغير الخاص $/
:
local $/ = "\r" # CR, use "\r\n" for CRLF or "\n" for LF
my $line = <FILE>;
يرى بيرلوك بيرلفار لمزيد من المعلومات.
حل آخر يعمل مع جميع أنواع عمليات التغذية المتمثلة في أن يفسد الملف بأكمله مرة واحدة ثم تقسيمه إلى خطوط باستخدام regex:
local $/ = undef;
my $content = <FILE>;
my @lines = split /\r\n|\n|\r/, $content;
يجب ألا تفعل ذلك بملفات كبيرة جدًا ، حيث يتم قراءة الملف في الذاكرة تمامًا. لاحظ أن إعداد $/ على القيمة غير المحددة يعطل تحديد الخط ، مما يعني أن كل شيء يتم قراءته حتى نهاية الملف.
نصائح أخرى
لقد حلت مشكلة أكثر عمومية يمكن أن تكون مفيدة هنا:
كيفية تحليل خط الملف الكبير على حدة مع أي محدد خط (CR/CRLF/LF) ، ولكن غير معروف مسبقًا.
ملف "Big" يعني أنه ليس من المقبول قراءة الملف بأكمله في متغير واحد. هنا وظيفة "اكتشاف" يحصل على اسم الملف وإرجاع إما " r" أو " n" ، كل ما يتم استخدامه لإنهاء الخط (تم البحث عن " r" أو " n 'Symbar نهاية الملف).
my $file = "test.txt";
local $/ = detectEndOfLine($file);
open(IN, $file) or die "Can't open file \"$file\" for reading: $!\n";
while(<IN>) {
s/\r\n|\n|\r$//;
print "$_\n";
}
sub detectEndOfLine {
my $file = $_[0];
my $size = -s $file;
print "\"$size\"\n";
open(IN, $file) or die "Can't open file \"$file\" for reading: $!\n";
for(my $i = $size; $i >= 0; --$i) {
seek(IN, $i, 0);
$_ = <IN>;
my $sym = substr($_, 0, 1);
return $sym if( $sym eq "\n" or $sym eq "\r" );
}
return undef;
}