6

ファイルハンドルから重複した行を印刷しようとしていますが、それらを削除したり、他の質問で尋ねられたものを削除したりすることはありません。私はこれをすばやく行うことができるほどperlの経験がないので、ここで質問します。これを行う方法は何ですか?

4

4 に答える 4

25

標準のPerlの省略形を使用する:

my %seen;
while ( <> ) { 
    print if $seen{$_}++;
}

「ワンライナー」として:

perl -ne 'print if $seen{$_}++'

より多くのデータ?これは印刷します<file name>:<line number>:<line>

perl -ne 'print ( $ARGV eq "-" ? "" : "$ARGV:" ), "$.:$_" if $seen{$_}++'

の説明%seen

  • %seenハッシュを宣言します。入力内の一意のwhile(<>)行(この場合はから取得)ごと$seen{$_}に、行のテキストで指定されたハッシュにスカラースロットがあります(これは、中かっこ$_で行われていることです)。{}
  • 接尾辞のインクリメント演算子(x++)を使用して、式の値を取得し、式の後にインクリメントすることを忘れないでください。したがって、行$seen{$_}が未定義であることが「確認」されていない場合、このように数値の「コンテキスト」に強制されると、0と見なされ、 falseになります。
  • 次に、1にインクリメントされます。

したがって、whileが実行を開始すると、すべての行が「ゼロ」になり(行を「ではない」と考えるのに役立つ場合%seen)、最初に行が表示されたときにperl、未定義の値を取得します。これは失敗しif、増分します。スカラースロットでのカウントは1になります。したがって、if条件を通過して出力される将来の発生に対しては1になります。

上で述べたように%seen、ハッシュを宣言しますが、strictオフにすると、任意の変数式をその場で作成できます。したがって、perlが初めてそれを見る$seen{$_}と、私が探していることを知ってい%seenますが、それを持っていないので、それを作成します。

これについての追加の素晴らしいことは、最後に、それを使用することを気にすると、各行が繰り返された回数のカウントがあるということです。

于 2011-05-04T13:50:26.517 に答える
3

これを試して

#!/usr/bin/perl -w
use strict;
use warnings;

my %duplicates;
while (<DATA>) {
    print if !defined $duplicates{$_};
    $duplicates{$_}++;
}
于 2011-05-04T13:50:32.160 に答える
3

複製を1回だけ印刷します。

perl -ne "print if $seen{$_}++ == 1"
于 2011-11-02T20:08:01.643 に答える
1

Unixライクなシステムを使用している場合は、次を使用できますuniq

uniq -d foo

また

uniq -D foo

あなたがやりたいことをする必要があります。詳細:manuniq

于 2011-05-04T16:07:37.963 に答える