行に異なる文字が2つ以上あることを確認してください。

行に異なる文字が2つ以上あることを確認してください。

各行に1つの単語を含むテキストファイルがあります。複数の文字を含まない行を削除しようとしています。たとえば、ファイルは次のようになります。

words
books
aaa
letters 
zzzz

出力ファイルが次のようになります。

words
books
letters

uniq -c私はthenを使って単語をグループ化するのではなく、各単語を個々の文字に分割しようとしましたが、wc -lif文に閉じ込められました。また、これを行うより簡単な方法があるべきだと思います。この問題を解決する他の方法は考えられません。

ベストアンサー1

あなたが意味すると仮定特徴文字の代わりに(例えば、文字でなくても、またはを...含む行を削除したい場合):11.1

grep -vx -e '' -e '\(.\)\1*'

または:

grep -vx '\(\(.\)\2*\)\{0,1\}'

つまり、-v1文字()で.始まり、その後に同じ文字(\1キャプチャされたコンテンツの逆参照)が続く空白行()を削除()します。行が終わるまで\(...\)0回以上()繰り返されます(パターンを先頭に固定)。行と終わり)。*-x

標準EREには逆参照がないため(BREのみ)、ここではegrepまたはを使用できません。grep -E

2つ以上の異なる文字を含む行の場合、他の種類の文字は無視されます([[:alpha:]]ここでは手紙、つまり考慮されるすべての文字アルファベット順にあなたの地域で):

grep -vx '[^[:alpha:]]*
[^[:alpha:]]*\([[:alpha:]]\)\([^[:alpha:]]*\1\)*[^[:alpha:]]*'

(2行でこれは2つの異なるモードを渡す別の方法です。)または:

grep -vx '[^[:alpha:]]*\([^[:alpha:]]*\([[:alpha:]]\)\([^[:alpha:]]*\2\)*[^[:alpha:]]*\)\{0,1\}'

これにより、12345aaa(1文字のみ)や(文字なし)などの-+-+-+-行が削除されます。

行を削除するにはAaaa(たとえば、文字を比較するときに大文字と小文字を無視する)、この-iオプションを追加します。

文字レベルで機能するため、複数の文字で表される文字がある場合は、期待どおりに機能しない可能性があります。たとえば、次の出力に似た行を削除します。

 $ printf 'e\u0300e\u0301\n'
 èé

(GNUprintfまたは互換性があると仮定)しかし、次のようなものではありません。

 $ printf '\ue8\ue9\n'
 èé

e\u300磁素の分解および\ue8プレ結合形態はどこにありますかèe(U+0065)およびè(U+00E8)はアルファベット順にただし、アクセント/アクセントと組み合わせたU+0300またはU+0301は除く)。

pcregrep文字を使用するには、またはGNUgrepとそのオプションを使用できます-P

最初のケース(少なくとも2つの異なる文字列クラスタ):

grep -vxP '(?:(\X)\1*)?'

2番目のケース(少なくとも2つの異なる場合があります)。手紙磁素クラスタ):

grep -vxP '(?:(?=\PL)\X)*(?:((?=\pL)\X)(?:(?:(?=\PL)\X)*\1(?!\pM))*(?:(?=\PL)\X)*)?'

(?=\PL)\Xアルファベット文字以外のクラスター(非アルファベット()とアルファベット文字スペースクラスターで始まる\X場合、文字スペースクラスター())はどこにありますか?(?=...)\PL(?=\pL)\X

\pLマッチ手紙Unicodeを編集してください。 POSIX 文字クラスとは異なり、アルファベット以外のスクリプト[:alpha:]の文字も含まれます。

e\u300\u301、 、 がすべて鋭くアクセントのあるaであってe\u301\u300も、4つの異なるクラスタとして扱われます\ue9\u300\ue8\u301e

また、1文字に複数の文字を含む(U + FB03)などの文字にも注意してください。特徴


PCREを使用すると、次のこともできます。ポジティブ方法:

  • 少なくとも2つの異なる文字:

    grep -P '(.).*(?!\1).'
    
  • 少なくとも2つの異なるアルファベット文字:

    grep -P '(\pL).*(?!\1)\pL'
    
  • 少なくとも2つの異なる文字列クラスター:

    grep -P '^\X*(\X)\X*(?!\1(?!\pM))\X'
    

    (少なくとも)コーラン韓国語の分解形態は正しく機能しません。 PCRE(perlREとは反対\b{g})にはAFAIK(子境界演算子)がなく、Unicode属性のサポートが制限されています。私たちは(?!\pM)近似として(この場合、「結合表示文字が従わない限り」を意味します)を使用しますが、これは複数の部分からなるハングルでは機能しません。手紙/音節その中でもキャラクター部分そのような財産はありません。려련련たとえば、削除します。今、誰もが次のように主張することができます。部分ユニーク手紙...

    perlバージョン5.22以降では、次のように書くことができます。

    perl -Mopen=locale -lne 'print if /\b{g}(\X).*\b{g}(?!\1\b{g})\X/'
    
  • 少なくとも2つの異なる手紙文字素クラスタ:

    grep -P '^\X*((?=\pL)\X)\X*(?!\1(?!\pM))(?=\pL)\X'
    

    繰り返しますが、適用されません려련련perl

    perl -Mopen=locale -lne 'print if /\b{g}(?=\pL)(\X).*\b{g}(?!\1\b{g})(?=\pL)\X/'
    

これにより、perl次のようなより直接的なアプローチを使用できます。

  • 少なくとも2つの異なる文字:

    perl -Mopen=locale -MList::MoreUtils=uniq -lne '
      print if uniq(/./g) >= 2'
    
  • 少なくとも2つの異なるアルファベット文字:

    perl -Mopen=locale -MList::MoreUtils=uniq -lne '
      print if uniq(/\pL/g) >= 2'
    
  • 少なくとも2つの異なる文字列クラスター:

    perl -Mopen=locale -MList::MoreUtils=uniq -lne '
      print if uniq(/\X/g) >= 2'
    
  • 少なくとも2つの異なる手紙文字素クラスタ:

    perl -Mopen=locale -MList::MoreUtils=uniq -lne '
      print if uniq(grep /^\pL/, /\X/g) >= 2'
    

おすすめ記事