[英]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.