sedを使用して、2つのアルファベット文字を含む行のみを見つけて維持します。

sedを使用して、2つのアルファベット文字を含む行のみを見つけて維持します。

次のような多くの行を含むファイルがあります。

33B87401
33B87402
33B87403
33B8EE44
33B87405
33B87406
33B87407
33B87408
33B87409
33B8740A
33B8740B
33B8740C
33B87D0D
33B8740E
33B8740F
33B87410
33B87411
33B87C1E
33B87CC3
33B87C1C

2つのアルファベットのみを含む行だけを保持する方法を探しています。

この例の出力は次のとおりです。

33B8740A
33B8740B
33B8740C
33B8740E
33B8740F

ここに別のリストがあります

8765C3E3
8765C3E4
8765C3E5
8765C3E6
8765C3E7
8765C3E8
8765C3E9
8765C3EA
8765C3EB
8765C3EC
8765C3ED
8765C3EE
8765C3EF
8765C3F0

sedとawkの多くの例を読んでみると、それを再現することは不可能に見えます。

ありがとう

答え1

sed -ne's/[[:alpha:]]//3;t' -e's//&/2p'  <in >out

... 1行のクラスの3番目の文字をs///置き換えます。[[:alpha:]]その後、t交換が成功したことを確認し、成功するとスクリプトから分岐します。

sed自動的に印刷するように指示されたので、-n3つ以上のアルファベット文字を含む入力行が出力から効果的に削除され、2番目の置換ステートメントによってs///残される唯一の入力行は、2つ以下のアルファベット文字を含む行です。

2番目の置換は//左側の空の正規表現を使用しますsed(より効率的)最近コンパイルされたものを参照/regexp/- だからs/[[:alpha:]]/...もう一度読むことができます。これはs///、1行目から2番目に現れるアルファベット文字を&それ自体に置き換えようとするため、効果的なno-opが発生し、行は実際には変更されません。ただし、これが正常に実行されると、その行も出力pに印刷されます。

要約すると、最初のs///置換は3つ以上のアルファベット文字に一致するすべての入力行を出力から効果的に削除し、2番目の置換は残りをp2つのアルファベット文字に一致する入力行のみを出力します。

...と/ grep...

grep -xE '([0-9]*[[:alpha:]]){2}' <in >out

声明は要求どおりに正確に従いません。入力では、英数字のみで構成される行のみを選択し、そのサブセット内の2文字以下の一致行のみを選択します。ここで、2番目の文字は最後の文字でなければなりません。このステートメントは、サンプル入力からサンプルに必要な出力を生成します。

ただし、要求されたとおりに実行してください。

grep -xE '([^[:alpha:]]*[[:alpha:]]){2}[^[:alpha:]]*'

このステートメントは、入力行の任意の場所にあり、^アルファベット以外の文字で区切ることができる2つのアルファベット文字に一致する入力行を選択します。

grepスイッチ-xは両方の場合に使用されます。ただし、^行開始アンカーと$行末アンカーが正規表現にそれぞれ追加(前に追加)されている場合は、2つのステートメントのいずれかを省略できます。この-xスイッチは全体的に一致 - したがって、正規表現は一致するすべての入力行を最初から最後まで完全に記述する必要があります。

答え2

私は以下を使用しますperl

perl -ne 'print if length s/\d//gr == 2'

以下を使用します。

  • -n暗黙のラッピングwhile ( <> ) {ループ
  • s///r元のテキストを変更せずに置き換えられたテキストを返します。
  • したがって、すべての数字を削除してから文字列の長さを見てみましょう。
  • 2の場合は、行を印刷します。

注:これにより、行から数字が削除され、数字以外の数字が残ります。代わりにこれを使用できます[^A-Z]

または - より明確な場合:

perl -ne 'print if (()=m/([A-Z])/g) == 2'

これはperlこのフラグをサポートしていない以前のバージョンで機能しますr。正規表現一致を使用してテキストを選択し、配列要素(一致)の数を計算します。 2の場合は、行を印刷します。

答え3

ちょうどあなたが望むものを正確に実行する簡単なPythonスクリプトを書いて、あなたの入力をテストしたところ、うまくいきます。

   #!/usr/bin/python

   def count_letters(input):
     count=0
     for char in input:
       if char.isalpha():
         count += 1
     return count

  fh=open('test_input','r')
  for line in fh.readlines():
    if count_letters(line) == 2 :
      print line

答え4

そしてawk

awk '{x=$0; gsub(/[^[:alpha:]]/, "", x)};length(x) == 2' file

これにより、各行を変数に設定し、xその中のアルファベット以外のすべての文字を空の文字列に置き換えます。x変更された長さが次xの場合、2関連する行が適しています。

またはgrep

grep '^[^[:alpha:]]*[:[:alpha:]][^[:alpha:]]*[:[:alpha:]][^[:alpha:]]*$' file

関連情報