2009-10-30 4 views
1

J'ai un grand fichier texte (plus de 70mb) et j'ai besoin de compter le nombre de fois qu'une séquence de caractères se produit dans le fichier. Je peux trouver beaucoup de scripts pour cela, mais aucun d'entre eux ne prend en compte qu'une séquence peut commencer et finir sur différentes lignes. Par souci d'efficacité (j'ai en fait beaucoup plus de 1 fichier que je suis en train de traiter), je ne peux pas pré-traiter les fichiers pour supprimer les retours à la ligne.Script shell Linux pour compter l'occurrence de la séquence char dans un fichier texte?

Exemple: Si je suis à la recherche de "thisIsTheSequence", le fichier suivant aurait 3 matches:

asdasdthisIsTheSequence 
asdasdasthisIsT 
heSequenceasdasdthisIsTheSequ 
encesadasdasda 

Merci pour l'aide.

+3

Vous pouvez prétraiter les fichiers, faire juste dans un pipeline avant le script de comptage: 'bande-retour à la ligne | count-matches'. –

Répondre

2

juste un script awk fera, puisque vous allez traiter un énorme fichier. Faire plusieurs tuyaux peut ralentir les choses.

#!/bin/bash 
awk 'BEGIN{ 
search="thisIsTheSequence" 
total=0 
} 
NR%10==0{ 
    c=gsub(search,"",s) 
    total+=c 
} 
NR{ s=s $0 } 
END{ 
c=gsub(search,"",s) 
print "total count: "total+c 
}' file 

sortie

$ more file 
asdasdthisIsTheSequence 
asdasdasthisIsT 
heSequenceasdasdthisIsTheSequ 
encesadasdasdaasdasdthisIsTheSequence 
asdasdasthisIsT 
heSequenceasdasdthisIsTheSequ 
encesadasdasda 
asdasdthisIsTheSequence 
asdasdasthisIsT 
heSequenceasdasdthisIsTheSequ 
encesadasdasda 

$ ./shell.sh 
total count: 9 
7

Une option:

echo $((`tr -d "\n" < file | sed 's/thisIsTheSequence/\n/g' | wc -l` - 1)) 

Il y a probablement des méthodes plus efficaces en utilisant les services publics en dehors du noyau de la coque - surtout si vous pouvez adapter le fichier en mémoire.

-1

utiliser quelque chose comme:

head -n LL filename | tail -n YY | grep text | wc -l 

où LL est la dernière ligne de la séquence et YY est le nombre de lignes dans la séquence (c.-à-LL - première ligne)

0

est-il jamais à avoir plus d'une nouvelle ligne dans votre séquence? Si ce n'est pas le cas, une solution consisterait à diviser votre séquence en deux et à rechercher les moitiés (par exemple, rechercher "thisIsTh" et aussi "eSequence"), puis revenir aux occurrences que vous trouvez et prendre un "plus près". regardez ", c'est-à-dire effacez les nouvelles lignes dans cette zone et recherchez une correspondance.

Fondamentalement, il s'agit d'une sorte de "filtrage" rapide des données pour trouver quelque chose d'intéressant.

+0

Non, la séquence comporte 9 caractères. Les lignes de moins de 9 caractères ne sont pas pertinentes pour la recherche – jdc0589

+0

Dans ce cas, vous pouvez rechercher les deux moitiés de la séquence. S'il est brisé sur deux lignes, vous trouverez au moins UNE des moitiés. C'est fondamentalement une technique de filtrage qui fonctionne bien (rapide) si les moitiés elles-mêmes sont assez rares. Mais c'est un peu d'effort à mettre en œuvre. – Artelius

Questions connexes