Come contare la ricorrenza di un modello in una linea


8

Ho un file che ha tre colonne. La colonna 3 contiene nomi di geni e si presenta così:

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

Come posso stampare il numero di geni in ogni riga?


Una quarta colonna? Cosa dovrebbe accadere se quella colonna è già occupata (seconda riga nel tuo esempio) o se le altre colonne sono vuote (ultima riga)?
Kusalananda

@Kusalananda Rimosso quel criterio dalla mia domanda :)
Saisha

A una rapida occhiata, tutte le risposte contano i campi o le stringhe separati da virgola che corrispondono al Rv*modello in qualsiasi punto della linea, non solo in una determinata colonna. Quindi noterò solo che se in realtà hai altri dati nel file, non presentati nella domanda qui, potresti dover modificare le soluzioni di conseguenza. (O chiarire la domanda.)
ilkkachu

Risposte:


10

Volete semplicemente aggiungere una colonna con il conteggio delle colonne. Questo può essere fatto usando awk:

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

NFè una awkvariabile che contiene il numero di campi (colonne) nel record corrente (riga). Stampiamo questo numero seguito da una virgola e dal resto della riga, per ogni riga.

Un'alternativa (stesso risultato, ma può sembrare un po 'più pulita):

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

FSè il separatore di campo che awkutilizza per dividere ogni record in campi e lo impostiamo su una virgola con -F ','sulla riga di comando (come nella prima soluzione). OFSè il separatore del campo di output e impostiamo che sia lo stesso di FSprima di leggere la prima riga di input.


5

Se si desidera contare il numero di occorrenze del Rv[0-9]{4}c?modello rispetto al numero di campi delimitati da virgole come suggerisce l'oggetto della domanda, è possibile:

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

4

Un approccio Perl:

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

Le -amarche si perlcomportano come awke dividono ogni riga di input sulla stringa fornita da -Fe salvano i campi risultanti nella matrice @F. Pertanto, $#Fsarà l'indice di array più alto in @Fe, poiché gli array iniziano a contare su 0, $#F+1sarà il numero totale di elementi nell'array. Il -pmezzo "stampa ogni riga di input dopo aver applicato lo script fornito da -e. L' s///operatore di sostituzione è qui e qui stavano sostituendo l'inizio della riga ( ^) con il numero di campi + 1 e una virgola ( $#F+1 . ",").


1

La tua domanda afferma che la colonna 3 contiene nomi di geni. Presumo che il tuo input effettivo sia il seguente:

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

Ogni nome di gene nella colonna 3 contiene una Rvsottostringa iniziale. Quindi possiamo contarli in Python in questo modo:

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

L'elenco risultante mostra il conteggio dei geni in ciascuna riga, nel loro rispettivo ordine. Se vogliamo renderlo più dettagliato e includere la possibilità che i geni non contengano una stringa "Rv" (ma supponiamo che column3 sia una stringa di valore separata da virgola), possiamo anche fare quanto segue:

#!/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))

Prova:

$ ./count_genes.py input.txt                                                                                             
Line 0 contains 3
Line 1 contains 4
Line 2 contains 1
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.