行内のパターンの発生を数える方法


8

3つの列を持つファイルがあります。列3には遺伝子の名前が含まれており、次のようになります。

Rv0729,Rv0993,Rv1408  
Rv0162c,Rv0761c,Rv1862,Rv3086  
Rv2790c

各行の遺伝子の数をどのように印刷できますか?


4列目?その列が既に占有されている場合(例では2行目)、または他の列が空の場合(最後の行)はどうなりますか?
クサラナンダ

@Kusalanandaは:)私のクエリからその基準を削除
Saisha

簡単に見ると、すべての回答Rv*は、特定の列だけでなく、行のどこかにあるパターンに一致するコンマ区切りのフィールドまたは文字列を数えます。したがって、ここで質問に示されていない実際にファイルに他のデータがある場合は、それに応じてソリューションを変更する必要がある場合があることに注意します。(または質問を明確にします。)
ilkkachu 2017年

回答:


10

列の数を含む列を追加したいだけです。これは以下を使用して行うことができますawk

$ awk -F ',' '{ printf("%d,%s\n", NF, $0) }' data.in
3,Rv0729,Rv0993,Rv1408
4,Rv0162c,Rv0761c,Rv1862,Rv3086
1,Rv2790c

NFあるawk現在のレコード(行)のフィールド(列)の数を含む変数。各行について、この番号に続いてコンマと残りの行を出力します。

別の方法(同じ結果ですが、少しすっきり見えるかもしれません):

$ awk -F ',' 'BEGIN { OFS=FS } { print NF, $0 }' data.in

FSは、awk各レコードをフィールドに分割するために使用するフィールドセパレーター-F ','です。コマンドラインで(最初のソリューションのように)を使用して、これをコンマに設定します。OFSある出力フィールドセパレータが、我々はそれが同じになるように設定FS入力の最初の行を読み取る前に。


5

Rv[0-9]{4}c?質問の件名が示すように、コンマ区切りのフィールドの数ではなく、パターンの出現回数を数えたい場合は、次のようにします。

 awk '{print gsub(/Rv[0-9]{4}c?/, "&"), $0}'

4

Perlのアプローチ:

$ perl -F, -pae 's/^/$#F+1 . ","/e' file
3,Rv0729,Rv0993,Rv1408  
4,Rv0162c,Rv0761c,Rv1862,Rv3086  
1,Rv2790c

-a作るには、perlのように振る舞うawkとによって与えられた文字列に、各入力行を分割し-F、配列に結果フィールドとセーブ@F。したがって、$#Fはで最も高い配列インデックスで@Fあり、配列はでカウントを開始するため、配列内の要素の総数0$#F+1なります。-p手段は「によって与えられたスクリプトをaplpyingした後、すべての入力行を印刷する-es///置換演算子であり、ここで行(の始まりを交換しているし、^フィールド+ 1の数とカンマ(と)$#F+1 . ",")。


1

あなたの質問は、列3には遺伝子の名前が含まれていると述べています。私はあなたの実際の入力は次のとおりだと思います:

column1 column2 Rv0729,Rv0993,Rv1408  
column1 column2 Rv0162c,Rv0761c,Rv1862,Rv3086  
column1 column2 Rv2790c

column3の各遺伝子名には、先行するRvサブストリングが含まれています。したがって、Pythonでそれらを次のようにカウントできます。

$ python -c  "import sys;print map(lambda x: x.split()[2].count('Rv'),sys.stdin.readlines())"  < input.txt               
[3, 4, 1]

結果のリストには、各行の遺伝子数がそれぞれの順序で表示されます。さらに冗長にして、遺伝子に「Rv」文字列が含まれていない可能性を含める場合(ただし、column3はコンマ区切りの値文字列であると想定)、次のようにすることもできます。

#!/usr/bin/env python
import sys
with open(sys.argv[1]) as fd:
    for index,line in enumerate(fd):
        columns = line.strip().split()
        num_genes=len(columns[2].split(","))
        print("Line "+str(index)+" contains "+str(num_genes))

試運転:

$ ./count_genes.py input.txt                                                                                             
Line 0 contains 3
Line 1 contains 4
Line 2 contains 1
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.