我想从3G调制解调器中提取和记录各种参数,因为存在间歇性丢失。因此我使用wget从3G调制解调器读取3Ginfo.html
并将内容放入文件contents.txt
。使用Notepad ++打开此文件会显示所有数据。
由于我的声誉,我无法发布图片,因此下面的代码是我能做的最好的;从Notepad ++(打开View All Characters),我得到:
<tr>[LF]
<td class='hd'>Signal Strength:</td>[LF]
<td>[LF]
-72[CR]
 (dBm) (High)</td>[LF]
</tr>[LF]
但是,当从Perl逐行读取文件时,显然存在的行数少于Notepad ++报告的数据并且数据丢失。在这种情况下,缺少实际的信号强度值。
以下是读取文件的Perl代码:
open hLOGFILE, "<output.txt";
while (<hLOGFILE>)
{
print "Line no $. Text is $_ ";
}
这是输出(作为文字,因为我还不能发布图片):
Line no 98 Text is <tr>
Line no 99 Text is <td class='hd'>Signal Strength:</td>
Line no 100 Text is <td>
 (dBm) (High)</td>
Line no 102 Text is </tr>
很明显,缺少行并且它与行终止符的<cr>
结尾有关。我试过啜饮文件,但线条仍然缺失。
除了逐字节读取然后尝试以这种方式解析文件(这不是很吸引人)之外我找不到解决方案。
我的计划是每分钟左右简单地提取和记录感兴趣的行。
我尝试打开指定各种编码的文件,但仍然没有快乐。如果Notepad ++可以读取并显示所有数据,为什么它在Perl中不起作用。从Windows XP命令行使用more
时,它会显示数据也丢失。
当我从chrome查看来源时,
<tr>
<td class='hd'>Received Signal Code Power(RSCP):</td>
<td align='center'> -78 dBm</td>
</tr>
答案 0 :(得分:1)
-72[CR]
行缺少。你只是没有看到它。
这是因为它不是行,因为回车字符通常不会被识别为换行符。发生的事情是你正在读这一行:
-72[CR] (dBm) (High)</td>[LF]
正在发生的事情是你正在打印:
Line No. 101 is -72
然后打印回车符,使光标返回到行的开头。然后,打印该行的其余部分。这会掩盖您打印出来的内容,因此您会看到:
 (High)</td>
因为它覆盖了该行的前一个文本。
我使用VI创建三种不同文件格式的三种不同文件(“mac”=“\ r”,“unix”=“\ n”和“dos”=“\ r \ n”),然后我使用Unix cat命令将它们组合成一个单独的文件。
这是我的计划:
use 5.12.0;
use autodie;
open my $test_fh, "<:crlf", "new_test";
local ($/); #Enable "slurp" mode
my $file = <$test_fh>; #Whole file is read in.
$file =~ s/[\r\n]+/\n/g; #Make all line endings just \n
#
# Now "rewrite" the file
#
my @file = split /\n/, $file;
for my $line (@file) {
say qq(Line: "$line");
}
打印出来:
Line: "MAC FILE"
Line: "this"
Line: "is"
Line: "a"
Line: "test of my"
Line: "program"
Line: "this"
Line: "WINDOWS FILE"
Line: "is"
Line: "a"
Line: "test of my"
Line: "program"
Line: "UNIX FILE"
Line: "this"
Line: "is"
Line: "a"
Line: "test of my"
Line: "program"
正如您所看到的, MAC FILE 确实显示了所有行,但单词Line:
没有打印出所有行。那是因为Perl把它读成一条大线。我的s/\r+/\n/g
将其转换为多行打印,但while
循环将其作为单行读取。
查看我的open
声明。我使用三个参数来解决Perl中的一些小问题。好处是你可以将图层或编码附加到文件。例如,<:crlf
会自动将Windows文件从\r\n
结尾转换为\n
,但不会触及Unix文件。对于那些在混合Unix / Windows环境中工作的人来说,这可以节省生命。
我希望为旧的 Mac 样式的文本文件找到一些类似的图层(在Mac OS X之前的几天,Macintosh文件仅以\r
结束而没有{{1}这真的解决了这个问题。不幸的是,我没有找到任何文档。自从你有OS X之前的Macintosh文本文件以来已经有很长一段时间了。
答案 1 :(得分:0)
回车符\r
。它列在perldoc perlreref中。从您的输入中删除它,例如在您的循环中,可以这样做:
while (<hLOGFILE>) {
s/\r//g;
print "Line no $. Text is $_ ";
}
替代
tr/\r//d; # same thing as above, really
s/[\r\n]+$//; # remove all line endings
答案 2 :(得分:0)
你可以把它扼杀()...
open hLOGFILE, "<output.txt";
while (<hLOGFILE>)
{
chomp();
print "Line no $. Text is $_ \n" if( $_ );
}
在某些系统上,我已经看到需要调用chomp()两次,以摆脱多个行尾字符......是的确存在。您可能还想添加一些内容来删除所有这些HTML标记?请参阅:How can I strip HTML in a string using Perl?