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>
Cela doit être fait en trois étapes:
Sélectionnez le numéro de ligne N (par exemple, utilisez la ligne 42):
sed '42!d'
Recherchez dans la ligne toutes les occurrences d'un modèle spécifique (ici la chaîne/expression régulière hello
name__) et imprimez-les séparément:
grep -o 'hello'
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
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.
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:
-c
, où les commandes sont contenues dans des guillemets simples;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
.[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.i==2
ne filtrera que la ligne dont l'indice est égal à 2. C'est ainsi que nous savons quelle ligne extraire.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.print()
. Ainsi, quel que soit le numéro renvoyé par la méthode .count()
, celui-ci apparaîtra à l'écran.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
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
awk
solution:
awk 'NR==X { print gsub("Word",""); }' file
X
avec votre numéro de ligne spécifique.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
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>