grepは一意の大文字のフレーズを抽出します。

grepは一意の大文字のフレーズを抽出します。

次のコードスニペットは、入力テキストのすべての大文字のリストを生成します。

grep -o '[^ ]*[[:upper:]][^ ]*' book_text.txt > Capitalized_words.txt

ここで、長さに関係なく、大文字でマークされた固有のフレーズの発生回数を抽出して計算したいと思います。

つまり、大文字の最初の文字を共有するスペースで区切られた単語の一意の文字列数が必要です。提供された唯一のフレーズには、句読点や大文字以外の単語が含まれていないため、2つのフレーズとにUniversity of British Columbiaなります。UniversityBritish Columbia

入力例:

Harvard archaeologists in Mexico also participated in the International
School of American Archaeology and Ethnology in Mexico City with scholars from
Mexico, Prussia and the United States.

予想出力:

1 - Harvard
1 - International School
1 - American Archaeology
1 - Ethnology
1 - Mexico City
2 - Mexico
1 - Prussia
1 - United States

例では、とは、Mexico単語Mexico Cityを共有する2つの異なる固有の構文です。

ベストアンサー1

GNU grepPCREを使用してビルドする場合は、以下をサポートします。

$ grep -Pow '(\p{Lu}\w*)(\s+(?1))*' input | sort | uniq -c
      1 American Archaeology
      1 Ethnology
      1 Example Input
      1 Harvard
      1 International School
      2 Mexico
      1 Mexico City
      1 Prussia
      1 United States

または:

<input tr -s '[:space:]' '[ *]' |
  grep -Pow '(\p{Lu}\w*)(\s+(?1))*' |
  sort |
  uniq -c

空白文字(改行文字を含む)のすべてのシーケンスは、最初に単一の空白(たとえばExample InputExample Inputまたは)Example\nInputに変換されます。

-w該当しないので参考にしてください空間分離単語、単語の境界は単語と単語ではなく文字の間にあります(単語の文字は数字と下線です)。あなたが欲しいと言った? スペースで区切られた単語United Statesただし、これは代わりにまたは代わりUnited States.Mexico入力を期待することと矛盾します。Mexico, Prussia

また、[^ ]*[[:upper:]][^ ]*スペースで区切られた単語と一致します。含む大文字が 1 つ以上ありますが、先頭にある必要はありません。たとえば、fooBarまたはと一致します0xAB+12(?<!\S)\p{Lu}\S*大文字で始まるスペースで区切られた単語が必要です。

$ grep -Po '(?<!\S)(\p{Lu}\S*)(\s+(?1))*' input | sort | uniq -c
      1 American Archaeology
      1 Ethnology
      1 Example Input:
      1 International School
      1 Mexico
      1 Mexico City
      1 Mexico, Prussia
      1 United States."

Harvard全行があり、スペースExample Input: "Havard ..."で区切られた単語が大文字で始まらないため、欠落しています。)input"Harvard

in途中でいくつかを追加することもできます。of

$ grep -Pow '(\p{Lu}\w*)((\s+(in|of))?\s+(?1))*' input | sort | uniq -c
      1 Ethnology in Mexico City
      1 Example Input
      1 Harvard
      1 International School of American Archaeology
      2 Mexico
      1 Prussia
      1 United States

\w英語以外のテキストを扱う場合に置き換えることもできます((?=\w)\X)。つまり、単語文字、一致単語文字で始まる文字素クラスタ

$ echo $'Universidad Nacional Auto\u0301noma de Me\u0301xico' |
  grep -Pow '(\p{Lu}\w*)((\s+(in|of|de))?\s+(?1))*' | sort | uniq -c
      1 Me
      1 Universidad Nacional Auto
$ echo $'Universidad Nacional Auto\u0301noma de Me\u0301xico' |
  grep -Pow '((?=\p{Lu})\X((?=\w)\X)*)((\s+(in|of|de))?\s+(?1))*' |
  sort | uniq -c
      1 Universidad Nacional Autónoma de México

Barではまだ一致しています$'foo\u0301Bar'

さらに、単語の文字/小文字および/または区切り文字で覆われる名前の構成を具体化する必要があるかもしれません。樹脂の台所オブライアン小学校ジャン・ポール・サルトル高校、等。

これらすべてをまとめると、次のように終わります。

first_grapheme='(?: (?= \p{Lu} ) \X )'
word_character="[\w'-]"
 word_grapheme="(?: (?= $word_character ) \X )"
          word="$first_grapheme $word_grapheme *"
     separator='(?: [ ] (?: in | on | of | de | en ) )? [ ]'

<input tr -s '[:space:]' '[ *]' |
  grep -Po "(?x) (?<! \pM | $word_character ) $word (?: $separator $word ) *" |
  sort |
  uniq -c

おすすめ記事