1

断続的なドロップアウトがあるため、3G モデムからさまざまなパラメータを抽出してログに記録したいと考えています。そのため、wget を使用3Ginfo.htmlして 3G モデムから読み取り、コンテンツをファイルに配置していますcontents.txt。Notepad++ を使用してこのファイルを開くと、すべてのデータが表示されます。

私の評判のため、写真を投稿することはできません。したがって、以下のコードは私ができる最善の方法です。Notepad++ から ([すべての文字を表示] をオンにして)、次のようになります。

<tr>[LF]

<td class='hd'>Signal Strength:</td>[LF]

<td>[LF]

-72[CR]

&nbsp(dBm)&nbsp(High)</td>[LF]

</tr>[LF]

ただし、Perl からファイルを 1 行ずつ読み取ると、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>

&nbsp(dBm)&nbsp(High)</td>

Line no 102  Text is </tr>

<cr>欠落している行があり、それが行末ターミネータに関連していることは明らかです。ファイルを丸呑みしようとしましたが、まだ行がありません。

バイトごとに読み取り、その方法でファイルを解析しようとすることを除けば (これはあまり魅力的ではありません)、解決策が見つかりません。

私の計画は、関心のある行を約 1 分ごとに単純に抽出してログに記録することです。

さまざまなエンコーディングを指定してファイルを開こうとしましたが、まだ喜びはありません。Notepad++ がすべてのデータを読み取って表示できる場合、なぜ Perl で機能しないのですか。Windows XP コマンド ラインから使用moreすると、データも失われていることが示されます。

クロムからソースを表示すると、

<tr>
    <td class='hd'>Received Signal Code Power(RSCP):</td>
    <td align='center'> -78 dBm</td>
</tr>
4

3 に答える 3

1

-72[CR]行が欠落していません。あなたはそれを見ていないだけです。

これは、通常、キャリッジ リターン文字が改行文字として認識されないため、行ではないためです。何が起こっているかというと、これを 1 行として読んでいるということです。

-72[CR]&nbsp(dBm)&nbsp(High)</td>[LF]

そして、何が起こっているかというと、あなたが印刷しているということです:

Line No. 101 is -72

次に、そのキャリッジリターン文字が印刷され、カーソルが行の先頭に戻ります。次に、残りの行が印刷されます。これにより、印刷したものが隠され、次のことがわかります。

&nbsp(High)</td>

その行の前のテキストを上書きしたためです。

VI を使用して、3 つの異なるファイル形式 ("mac" = "\r"、"unix" = "\n"、および "dos" = "\r\n") で 3 つの異なるファイルを作成し、次に 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 がそれを 1 つの大きな行として読み込んだためです。私s/\r+/\n/gはそれを複数行で印刷するように変換しましたが、whileループはそれを単一行として読み取りました。

私のopen発言を見てください。Perl の小さな問題を解決する 3 つのパラメーターを使用します。良いことは、レイヤーまたはエンコーディングをファイルに添付できることです。たとえば、 はWindows ファイルの末尾を<:crlfから に自動的に変換しますが、Unix ファイルには影響しません。Unix/Windows が混在する環境で作業する人にとっては、命の恩人です。\r\n\n

古いMacスタイルのテキスト ファイル用の同様のレイヤーを見つけたいと思っていました (Mac OS X より前の時代には、Macintosh ファイルは a だけで終わり、\rno\nがまったくありませんでした。そうすれば、問題は本当に解決したはずです。残念ながら、何も見つかりませんでした。 OS X より前の Macintosh テキスト ファイルがあったのは久しぶりです。

于 2013-03-01T03:52:18.807 に答える
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
于 2013-03-01T02:05:08.830 に答える
0

あなたはそれをむさぼり食うことができます...

open hLOGFILE, "<output.txt";
while (<hLOGFILE>)
{
    chomp(); 
    print "Line no $.  Text is $_ \n" if( $_ );
}

一部のシステムでは、複数の行末文字を取り除くために chomp() を 2 回呼び出す必要があることがわかりました...はい、存在します。これらの HTML タグをすべて削除するために、何かを追加することもできますか? 参照: Perl を使用して文字列内の HTML を削除するにはどうすればよいですか?

于 2013-03-01T03:49:35.773 に答える