سؤال

أحاول قراءة ملف يحتوي على 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;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top