Je veux compter les lignes entre "X". C'est juste un exemple; Je dois appliquer le code à un résultat biologique complexe. Je serai reconnaissant si vous pouvez suggérer une commande, de préférence en utilisant awk
, grep
ou sed
comme je les connais.
Exemple:
X
Y
Y
Y
X
Y
Y
Y
Y
X
Y
X
Sortie désirée:
3
4
1
Réponses:
Avec
awk
:Incrémentez un décompte pour chaque ligne ne contenant pas
X
; imprimer et réinitialiser le nombre de lignes contenantX
.la source
X
, le premier nombre de lignes serait toujours compté et généré avec cette solution, jusqu'à ce que la première ligne avecX
soit mise en correspondance. EX (ne peut pas ajouter de nouvelles lignes dans les commentaires, mais considérez qu'il y a une nouvelle ligne entre chaque caractère; P):Y X Y Y X Y Y Y
afficherait:1 2
END{if (count)print count}
), et la production d'une ligne vide où X était en début pour éviter que vous puissiez ajouter/X/&&count
en condition égalementY
s en tête ne doivent pas être comptés car ils ne sont pas exactement entre deuxX
s; l'autre se plaint que lesY
s finaux ne sont pas comptés car ils ne sont pas exactement entre deuxX
s. J'attendrai l'OP pour clarifier, si nécessaire; Je suis d'accord avec cette réponse telle qu'elle est jusque-là.Comment ça fonctionne:
Awk lit implicitement les fichiers d'entrée ligne par ligne.
/X/ && prev{print NR-prev-1}
Pour toute ligne contenant
X
et si nous avons précédemment attribué une valeur àprev
, imprimez le numéro de la ligne actuelleNR
, moinsprev
moins un./X/{prev=NR}
Pour toute ligne qui contient
X
, définissez la variableprev
au numéro de ligne en cours,NR
.la source
NR
me donne une idée:awk '/X/{print NR - 1; NR = 0}' foo
X
, il y a une petite différence dans la sortie entre les 2 réponses comme je l'ai expliqué dans un commentaire sous la réponse de muru.Une autre
awk
approche simple qui fonctionne sur les échantillons de données OP et si elleX
n'était pas dans le premier ou même dans les derniers X ou répétés.Au- dessus est correct quand il n'y a qu'un seul champ dans chaque ligne par défaut FS toutes les espaces blancs , sinon ci - dessous est révisée en cas général pour le comptage linewise . Vous pouvez entrer votre MOTIF en place de X là.
Exemple d'entrée:
La sortie est:
la source
La plupart des réponses correspondent au contenu de la ligne à compter à l'aide d'expressions régulières intégrées au programme Awk. Si vous devez faire correspondre des lignes avec du contenu qui peut contenir des caractères spéciaux (soit pour Awk ou des expressions régulières), il serait préférable de comparer réellement les chaînes pour l'égalité. Par conséquent, je propose le script Awk suivant comme variante de la réponse de muru :
Stockez-le sous forme de fichier texte, par exemple
count-rows.awk
, et invoquez-le comme suit:Vous pouvez ajuster la valeur de
needle
à votre guise. L'avantage de cette méthode est que vous pouvez appeler le programme à partir d'un script shell avec une valeur arbitraire pourneedle
sans échapper aux problèmes:la source