web-dev-qa-db-fra.com

Comment compter l'occurrence d'une chaîne spécifique sur une ligne spécifique d'un fichier?

Je sais que je peux utiliser wc pour renvoyer le nombre total de mots (et de lignes) d'un fichier en utilisant:

wc <filename>

Est-il possible de renvoyer le compte d'une chaîne spécifique sur une ligne spécifique d'un fichier?

Quelque chose comme ce qui suit:

wc -<flag> <line number> -<flag> <string> <filename>
6
Donald Peat

Cela doit être fait en trois étapes:

  1. Sélectionnez le numéro de ligne N (par exemple, utilisez la ligne 42):

    sed '42!d'
    
  2. Recherchez dans la ligne toutes les occurrences d'un modèle spécifique (ici la chaîne/expression régulière helloname__) et imprimez-les séparément:

    grep -o 'hello'
    
  3. Comptez les allumettes:

    wc -l
    

Ou pour le mettre dans un seul canal de commande, en lisant file.txt:

sed '42!d' file.txt | grep -o 'hello' | wc -l
9
Byte Commander

C’est un bon exemple pour mettre les outils Unix ensemble dans un pipeline.

line=5
str="ipsum"
sed -n "${line}p" filename | grep -o -- "$str" | wc -l

La commande sed p affiche la ligne donnée du fichier et l’alimente dans grep. L'option -o de Grep lui indique de sortir toutes les correspondances pour la chaîne donnée et chaque correspondance est sortie sur une ligne séparée. La sortie de Grep est fournie à wc, qui compte le nombre de lignes.

8
Mark Plotnick

Python

Voici une façon de le faire en Python via la compréhension de liste (voir ci-dessous la version abrégée alternative).

$ python -c 'import sys;print([ l for i,l in enumerate(sys.stdin,1) if i==2][0].count("Word"))' < input.txt                                          
3
$ cat input.txt
nothing here
Word and another Word, and one more Word
last line

Comment ça marche:

  • nous exécutons python interprète avec le drapeau -c, où les commandes sont contenues dans des guillemets simples;
  • le fichier d'entrée input.txt est redirigé dans le flux stdin de l'interprète python via l'opérateur < Shell. Nous avons donc besoin du module sys.
  • En utilisant la structure de compréhension de liste [something for item in something], nous lisons des lignes de texte à partir de sys.stdin.
  • enumerate(sys.stdin,1) nous permet de compter énumérer les lignes, c'est-à-dire qu'à chaque itération de compréhension de liste, nous allons obtenir la ligne de texte dans la variable l et l'indexer dans la variable i en commençant à 1.
  • Le i==2 ne filtrera que la ligne dont l'indice est égal à 2. C'est ainsi que nous savons quelle ligne extraire.
  • En conséquence, notre liste ne contiendra qu'un seul élément et son index est 0. Nous appelons donc cet élément [<list comprehension stuff here>][0]. -La .count("Word") est ce qui fait le travail de comptage. Par définition, il retourne un nombre d'occurrences non superposées d'une sous-chaîne dans une chaîne.
  • enfin tout cela était contenu dans la déclaration print(). Ainsi, quel que soit le numéro renvoyé par la méthode .count(), celui-ci apparaîtra à l'écran.

Version plus courte

Le moyen le plus rapide de procéder de la même manière dans Python consiste à utiliser la méthode readlines() à la place de la compréhension de liste et à faire référence à un élément spécifique de la liste produit par readlines(). Notez que readlines() génère une liste et que les listes dans Python sont indexées à 0, ce qui signifie que si vous souhaitez lire la ligne x, vous devez référencer l'élément de liste x-1. Par exemple,

$ python -c 'import sys;print(sys.stdin.readlines()[1].count("Word"))' < input.txt       
3

sed + grep

Bien sûr, nous n’avons pas à nous en tenir aux seuls langages de script. sed et grep fournissent des outils suffisants que nous pouvons utiliser pour répondre à nos besoins. Avec grep -c, nous pouvons compter l'occurrence de lignes correspondantes. Il suffit donc d'extraire la ligne spécifique dont nous avons besoin et de scinder tous les mots de cette ligne en lignes séparées. Ainsi:

$ sed -n  '2{s/ /\n/g;p}' input.txt | grep -c 'Word'
3
7

awk solution:

awk 'NR==X { print gsub("Word",""); }' file
  • changez le X avec votre numéro de ligne spécifique.
  • changer le "mot" avec votre mot désiré.
  • gsub retourne le numéro de remplacement du "mot", on dirait que nous le comptons.

Exampe:

$ cat file:
a b c a a d
d e f f f 1

voyons combien nous avons eu dans la ligne "2":

$ awk 'NR==2 { print gsub("f",""); }' file
3
6
Ravexina

Une façon de le faire, dans Perl:

Perl -lne '
  BEGIN{($lineno, $str) = splice @ARGV,0,2} 
  print $c = () = /$str/g if $. == $lineno
' <lineno> <string> <filename>
5
steeldriver