3つの連続した単語を検索してください。

3つの連続した単語を検索してください。

私の書籍リスト(txtファイル)には、次のような重複した書籍があります。 -

The Ideal Team Player
The Ideal Team Player: How to Recognize and Cultivate The Three Essential Virtues
Ideal Team Player: Recognize and Cultivate The Three Essential Virtues

Joy on Demand: The Art of Discovering the Happiness Within
Crucial Conversations Tools for Talking When Stakes Are High
Joy on Demand

Search Inside Yourself: The Unexpected Path to Achieving Success, Happiness
Search Inside Yourself
......
......
......

重複した書籍を見つけて確認し、手動で削除する必要があります。検索してみると、線にはパターンが必要だとわかりました。

前任者。

部分行比較に基づいて重複行を削除する

ファイル内で部分的に繰り返される行を探し、各行が何回繰り返されるかを計算しますか?

しかし、私の場合、線のパターンを見つけるのは難しかった。しかし、私は単語の順序でパターンを見つけました。

3つの連続した単語がある行だけを重複して表示したいと思います。(大文字と小文字を区別しない)

見ればわかるけど―――

The Ideal Team Player
The Ideal Team Player: How to Recognize and Cultivate The Three Essential Virtues
Ideal Team Player: Recognize and Cultivate The Three Essential Virtues

Ideal Team Player私が探している連続語。

出力が次のように表示されます。

3 Ideal Team Player
2 Joy on Demand
2 Search Inside Yourself
......
......
......

どうすればいいですか?

答え1

次のawkプログラムは、3つの連続した単語で構成される各グループの発生回数を格納し(句読点が削除された後)、数が1より大きい場合は、数と最後の単語のグループを印刷します。

{
        gsub("[[:punct:]]", "")

        for (i = 3; i <= NF; ++i)
                w[$(i-2),$(i-1),$i]++
}
END {
        for (key in w) {
                count = w[key]
                if (count > 1) {
                        gsub(SUBSEP," ",key)
                        print count, key
                }
        }
}

あなたの質問にテキストが与えられた場合、これは次のようになります。

2 Search Inside Yourself
2 Cultivate The Three
2 The Three Essential
2 Joy on Demand
2 Recognize and Cultivate
2 Three Essential Virtues
2 and Cultivate The
2 The Ideal Team
3 Ideal Team Player

ご覧のとおり、これはあまり役に立ちません。

代わりに、同じ数の情報を収集してからファイルを2番目に渡すことで、数が1より大きい単語の三重項を含む各行を印刷できます。

NR == FNR {
        gsub("[[:punct:]]", "")

        for (i = 3; i <= NF; ++i)
                w[$(i-2),$(i-1),$i]++

        next
}

{
        orig = $0
        gsub("[[:punct:]]", "")

        for (i = 3; i <= NF; ++i)
                if (w[$(i-2),$(i-1),$i] > 1) {
                        print orig
                        next
                }
}

ファイルをテストします。

$ cat file
The Ideal Team Player
The Ideal Team Player: How to Recognize and Cultivate The Three Essential Virtues
Ideal Team Player: Recognize and Cultivate The Three Essential Virtues

Joy on Demand: The Art of Discovering the Happiness Within
Crucial Conversations Tools for Talking When Stakes Are High
Joy on Demand

Search Inside Yourself: The Unexpected Path to Achieving Success, Happiness
Search Inside Yourself
$ awk -f script.awk file file
The Ideal Team Player
The Ideal Team Player: How to Recognize and Cultivate The Three Essential Virtues
Ideal Team Player: Recognize and Cultivate The Three Essential Virtues
Joy on Demand: The Art of Discovering the Happiness Within
Joy on Demand
Search Inside Yourself: The Unexpected Path to Achieving Success, Happiness
Search Inside Yourself

警告:awkプログラムはファイルテキストの約3倍を格納するのに十分なメモリを必要とし、アイテムが実際に重複していなくても一般的なフレーズで重複するアイテムを見つけることができます(たとえば、「料理方法」は複数のタイトルのトピックである可能性があります)。書籍)。

答え2

IMO、これは3つの連続した単語を見つけるよりも、単語セットの交差点を使用してよりよく解決されます。

したがって、次のPerlスクリプトは次のことを行います。いいえ3つの連続した単語を見つけてください。代わりに、まず(標準入力および/または1つ以上のファイルから)入力全体を読み取り(使用)コレクション::小さいモジュール)は、各入力ラインのワードセットを生成します。

次に、入力を2番目に処理し(各行について)、正確に重複する行または行の最初のパスで読み取ったすべての行を印刷します。交差点コレクションに3つ以上の要素

ハッシュ配列を使用して%sets各タイトルの単語セットを保存し、別のハッシュを使用して%titles各タイトルを見た回数を計算します。これは、出力フェーズでタイトルが次よりも頻繁に印刷されないようにするために使用されます。入力に表示される前に。

つまり、重複した行に似た行(たとえば、3つ以上の同じ単語を含む行)を並べて印刷します。 3つの単語が連続する必要はありません。

スクリプトはコレクションを構築するときにいくつかの非常に一般的な小さな単語を無視しますが、この機能はコメント化された行をコメントアウトまたは削除することで無効にすることができますOPTIONAL...。または、必要に応じてよく使用される単語のリストを編集することもできます。

スクリプトの小さな単語リストに単語が含まれていることに言及する価値がありますby。必要に応じてリストから削除できますが、存在する理由はbyプラスでスクリプトが一致するのを防ぐためです。どの他の2つの単語 - たとえば、一致Aardvark Taxidermy for Personal Wealth by Peter SmithしますThe Wealth of Nations by Adam Smith(一致byと)。最初の本は(私が望む)まったく存在しませんが、もし存在しているなら、それは経済学の教科書とは全く関係がありません。WealthSmith

注:このスクリプトは、入力行ごとに関連する単語のセットとともに、入力全体をメモリに保存します。数GiBの利用可能なRAMを備えた最新のシステムでは、入力が非常に大きくない限り問題はありません。

注2:Set::TinyDebian用にパッケージ化されておりlibset-tiny-perl、他のディストリビューション用にもプリパッケージされています。それ以外の場合は、上記のCPANリンクから入手できます。

#!/usr/bin/perl -w

use strict;
use Set::Tiny;

# a partial list of common articles, prepositions and small words joined into
# a regex.
my $sw = join("|", qw(
  a about after against all among an and around as at be before between both
  but by can do down during first for from go have he her him how
  I if in into is it its last like me my new of off old
  on or out over she so such that the their there they this through to
  too under up we what when where with without you your)
);

my %sets=();    # word sets for each title.
my %titles=();  # count of how many times we see the same title.

while(<>) {
  chomp;
  # take a copy of the original input line, so we can use it as
  # a key for the hashes later.
  my $orig = $_;

  # "simplify" the input line
  s/[[:punct:]]//g;  #/ strip punctuation characters
  s/^\s*|\s*$//g;    #/ strip leading and trailing spaces
  $_=lc;             #/ lowercase everything, case is not important.
  s/\b($sw)\b//iog;  #/ optional. strip small words
  next if (/^$/);

  $sets{$orig} = Set::Tiny->new(split);
  $titles{$orig}++;
};

my @keys = (sort keys %sets);

foreach my $title (@keys) {
  next unless ($titles{$title} > 0);

  # if we have any exact dupes, print them. and make sure they won't
  # be printed again.
  if ($titles{$title} > 1) {
    print "$title\n" x $titles{$title};
    $titles{$title}  = 0;
  };

  foreach my $key (@keys) {
    next unless ($titles{$key} > 0);
    next if ($key eq $title);

    my $intersect = $sets{$key}->intersection($sets{$title});
    my $k=scalar keys %{ $intersect };

    #print STDERR "====>$k(" . join(",",sort keys %{ $intersect }) . "):$title:$key\n" if ($k > 1);

    if ($k >= 3) {
      print "$title\n" if ($titles{$title} > 0);
      print "$key\n" x $titles{$key};
      $titles{$key}   = 0;
      $titles{$title} = 0;
    };
  };
};

たとえば、として保存しblueray.plて実行可能にしますchmod +x

新しいサンプル入力が与えられると、次の出力が生成されます。

$ ./blueray.pl TestData.txt 
7L: The Seven Levels of Communication
The Seven Levels of Communication: Go From Relationships to Referrals by Michael J. Maher
A History of Money and Banking in the United States: The Colonial Era to World War II
The History of Banking: The History of Banking and How the World of Finance Became What it is Today
America's Bank: The Epic Struggle to Create the Federal Reserve
America's Money Machine: The Story of the Federal Reserve
Freakonomics: A Rogue Economist
Freakonomics: A Rogue Economist Explores the Hidden
Freakonomics: A Rogue Economist Explores the Hidden
Freakonomics: A Rogue Economist Explores the Hidden Side of Everything by Steven Levitt
Money Master the Game by Tony Robbinson
Money Master the Game by Tony Robbinson
Money Master the Game by Tony Robbinson
The Federal Reserve and its Founders: Money, Politics, and Power
The Power and Independence of the Federal Reserve
Venture Deals by Brad Feld
Venture Deals by Brad Feld & Jason Mendelson
Zen and the Art of Motorcycle Maintenance: An Inquiry into Values
Zen and the Art of Motorcycle Maintenance: An Inquiry into Values

これは、例の出力とまったく同じではありません。正確な順序を無視し、タイトルに一般的な単語があるかどうかを確認するので、誤解の可能性が高くなります。そして逃してはいけないゲームを見逃す可能性が少ない(偽の否定)。

試してみるか、どの単語が一致するか(またはほぼ一致するか)確認するには、この行#print STDERRのコメントを解除してください。

関連情報