特定の文字を除いて、行の文字数を数える方法は?


9

これはパーツファイルです

N W N N N N N N N N N
N C N N N N N N N N N
N A N N N N N N N N N
N N N N N N N N N N N
N G N N N N N N N N N
N C N N N C N N N N N
N C C N N N N N N N N

各行で、「N」以外のすべての文字の総数をカウントしたい

私の欲望の出力

1
1
1
0
1
2
2

sed気にしないものを置き換えたりawk、残りの長さを数えたりするために使用sed 's/N//g ; s/\s//g' file | awk '{ print length($0); }'
Rolf

回答:


13

GNU awkソリューション:

awk -v FPAT='[^N[:space:]]' '{ print NF }' file
  • FPAT='[^N[:space:]]'-フィールド値を定義するパターン(Ncharと空白を除く任意の文字)

予想される出力:

1
1
1
0
1
2
2


7

スペース文字以外の各行にカウントが必要であると想定し、 N

$ perl -lne 'print tr/N //c' ip.txt 
1
1
1
0
1
2
2
  • の戻り値は、tr置き換えられた文字数です
  • c 指定された文字セットを補完する
  • -lオプションの使用に注意してください。入力行から改行文字を取り除き、1つずれたエラーを回避し、printステートメントに改行文字を追加します。


より一般的なソリューション

perl -lane 'print scalar grep {$_ ne "N"} @F' ip.txt 
  • -a@F配列で保存された空白で入力行を自動的に分割するオプション
  • grep {$_ ne "N"} @F@F文字列と一致しないすべての要素の配列を返しますN
    • 正規表現の同等物は grep {!/^N$/} @F
  • を使用するとscalar、配列の要素数が得られます

6

代替のawkソリューション:

awk '{ print gsub(/[^N[:space:]]/,"") }' file
  • gsub(...)- gsub()関数は、行われた置換の数を返します。

出力:

1
1
1
0
1
2
2

6

別のawkアプローチ(空の行に対しては-1を返します)。

awk -F'[^N ]' '$0=NF-1""' infile

または、複雑な場合、空行では-1を返し、空白(タブ/スペース)行でのみ0を返します。

awk -F'[^N \t]+' '$0=NF-1""' infile

印刷されます-1...空行対のみN /スペースで構成された空行のために...しかし、その行を区別することが望ましいかもしれない
Sundeep

1
@Sundeepはい、そうです。行にタブまたはスペースのみが含まれ、0として示される私の更新も参照してください
2017年

5
  1. trおよびPOSIXシェルスクリプト:

    tr -d 'N ' < file | while read x ; do echo ${#x} ; done
    
  2. bash、、kshおよびzsh

    while read x ; do x="${x//[ N]}" ; echo ${#x} ; done < file
    

1
awk '{print length()}'より遅いシェルループを回避するために使用できますが、awk自体ですべて実行できます...
Sundeep

@Sundeep、それは真実です(両方が同時に開始された場合)、そのawkループシェルループよりも高速です。しかし、シェルは常にメモリ内にあり、awkそうでない可能性があります- awkまだロードされていない、またはスワップアウトされていない場合、シェルのロードのオーバーヘッド(失われる時間)は、実行の利点よりも大きくなる可能性がありますawk-特に小さなループ。このような場合(つまり、この場合)は遅くなるawk可能性があります
agc

まあ、確かに小さなものの時間について心配していません... unix.stackexchange.com/questions/169716/…を
Sundeep

1
@Sundeep、私心配します。少し前に、私はフロッピーベースのLinuxディストリビューションを使用していました。不必要にawkシェルスクリプトで使用すると、このようなシステムが4つすべてでクロールされる可能性があります。一般に、同じレイテンシのドラッグは、ファームウェアが制限されているシステム、または高負荷のシステムに適用されます。
agc 2017年

1

ショートの組み合わせtrawk

$ tr -d ' N' <file.in | awk '{ print length }'
1
1
1
0
1
2
2

これにより、入力ファイルからすべてのスペースとNが削除awkされ、各行の長さが出力されます。


0

もう1つの簡単な方法は、Pythonでそれを行うことです。これは、ほとんどのUNIX環境にプリインストールされています。次のコードを.pyファイルにドロップします。

with open('geno') as f:
    for line in f:
        count = 0
        for word in line.split():
            if word != 'N':
                count += 1
        print(count)

そして次に:

python file.py

端末から。上記の内容は次のとおりです。

  • 「geno」という名前のファイルの各行
  • カウンターを0に設定し、値が見つかるたびにインクリメントします!= 'N'
  • 現在の行の終わりに達したら、カウンターを印刷して次の行に移動します
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.