簡體   English   中英

在 Perl 中計算由 CR/LF(回車和換行符)分隔的記錄

[英]Counting records separated by CR/LF (carriage return and newline) in Perl

我正在嘗試創建一個簡單的腳本來讀取包含書名記錄的文本文件。 每條記錄都用一個普通的舊雙空格 ( \\r\\n\\r\\n ) 分隔。 我需要計算文件中有多少條記錄。

例如這里是輸入文件:

record 1
some text


record 2 
some text
...

我正在使用正則表達式來檢查回車和換行符,但它無法匹配。 我究竟做錯了什么? 我不知所措。

sub readInputFile {

    my $inputFile = $_[0]; #read first argument from the commandline as fileName

    open INPUTFILE, "+<", $inputFile or die $!;    #Open File

    my $singleLine;
    my @singleRecord;
    my $recordCounter = 0;

    while (<INPUTFILE>) {                    # loop through the input file line-by-line
        $singleLine = $_;
        push(@singleRecord, $singleLine);    # start adding each line to a record array

        if ($singleLine =~ m/\r\n/) {        # check for carriage return and new line
            $recordCounter += 1;
            createHashTable(@singleRecord);  # send record make a hash table
            @singleRecord = ();              # empty the current record to start a new record
        }

    }

    print "total records : $recordCounter \n";
    close(INPUTFILE);
}

聽起來您正在 Linux 上處理 Windows 文本文件,在這種情況下,您希望使用:crlf層打開該文件,這會將所有 CRLF 行結尾轉換為標准的 Perl \\n結尾。

如果您正在 Windows 平台上讀取 Windows 文件,那么轉換已經為您完成,您將不會在讀取的數據中找到 CRLF 序列。 如果您正在閱讀 Linux 文件,那么無論如何那里都沒有 CR 字符。

聽起來您的記錄也用空行分隔。 將內置輸入記錄分隔符變量$/設置為空字符串將導致 Perl 一次讀取整個記錄。

我相信這個版本的子程序正是你所需要的。 請注意,熟悉 Perl 的人會感謝您使用小寫字母和下划線作為變量和子程序名稱。 混合大小寫通常保留用於包名稱。

您沒有顯示create_hash_table所以我無法判斷它需要什么數據。 我已經將記錄切碎並分成幾行,並傳遞了刪除換行符的記錄中的行列表。 將整個記錄作為單個字符串傳遞並讓create_hash_table根據需要處理它可能會更好。

sub read_input_file {

    my ($input_file) = @_;

    open my $fh, '<:crlf', $input_file or die $!;
    local $/ = '';

    my $record_counter = 0;

    while (my $record = <$fh>) {
        chomp;
        ++$record_counter;
        create_hash_table(split /\n/, $record);
    }
    close $fh;

    print "Total records : $record_counter\n";
}

您可以通過更改 Perl 的記錄分隔符來更簡潔地執行此操作,這將使循環一次返回一條記錄而不是一次返回一行。

例如,打開文件后:

local $/ = "\r\n\r\n";
my $recordCounter = 0;
$recordCounter++ while(<INPUTFILE>);    

$/持有 Perl 的全局記錄分隔符,並且使用local來限定它的范圍允許您臨時覆蓋它的值,直到封閉塊的末尾,當它會自動恢復到以前的值時。

但聽起來您正在處理的文件實際上可能具有“\\n\\n”記錄分隔符,甚至“\\r\\r”。 您需要為正在處理的任何文件正確設置記錄分隔符。

如果您的文件不是巨大的數 GB 文件,最簡單和最安全的方法是讀取整個文件,並使用通用換行元字符\\R

這樣,如果某些文件實際上使用 LF 而不是 CRLF(甚至是舊的 Mac 標准 CR),它也可以工作。

如果您還需要實際記錄,請將其與split一起使用:

perl -ln -0777 -e 'my @records = split /\R\R/; print scalar(@records)' $Your_File

或者,如果您只想計算記錄:

perl -ln -0777 -e 'my $count=()=/\R\R/g; print $count' $Your_File

有關更多詳細信息,另請參閱我對類似問題的其他回答

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM