web-dev-qa-db-fra.com

Compter les lignes entre "X"

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 car je les connais bien.

Exemple:

X
Y
Y
Y
X
Y
Y
Y
Y
X
Y
X

Sortie désirée:

3
4
1
13
Rhea

Avec awkname__:

$ awk '!/X/{count++}/X/{print count; count = 0}' input

3
4
1

Incrémenter un compte pour chaque ligne ne contenant pas Xname__; affiche et réinitialise le nombre de lignes contenant Xname__.

13
muru
$ awk '/X/ && prev{print NR-prev-1} /X/{prev=NR}' file
3
4
1

Comment ça marche:

Awk lit implicitement ligne par ligne dans les fichiers d'entrée.

  • /X/ && prev{print NR-prev-1}

    Pour toute ligne contenant Xet si nous avons précédemment attribué une valeur à prevname__, imprimez le numéro de la ligne en cours, NRname__, minus prevnom____ moins un.

  • /X/{prev=NR}

    Pour toute ligne contenant Xname__, définissez la variable prevsur le numéro de ligne actuel, NRname__.

12
John1024

Une autre approche simple awk qui fonctionne sur les exemples de données d’OP et si X n’était pas dans le premier ou même dans les derniers X ou répétés.

awk -v RS='X' 'NF{print NF}' infile

Ce qui est indiqué ci-dessus est correct s'il n'y a qu'un seul champ dans chaque ligne avec la valeur par défaut FS tout d'espaces , sinon, ci-dessous est révisé dans le cas général permettant de compter ligne par ligne . Vous pouvez entrer votre MOTIF à la place de X il.

awk -F'\n' -v RS='X' 'NF>2{print NF-2}'

Exemple de saisie:

X
Y YYY Y
YY
YY Y YY YY Y Y
X
Y Y Y
X
Y
Y
X
X

La sortie est:

3
1
2
6
αғsнιη

La plupart des réponses ici correspondent au contenu de la ligne à compter en utilisant des expressions régulières intégrées au programme Awk. Si vous devez faire correspondre les lignes avec du contenu pouvant contenir des caractères spéciaux (soit en Awk, soit en expressions régulières), il est préférable de comparer les chaînes pour vérifier leur égalité. Je propose donc le script Awk suivant comme variante de réponse de mur :

BEGIN {
    count = 0;
}

{
    if ($0 == needle) {
        if (count) {
            print count;
            count = 0;
        }
    } else {
        count++;
    }
}

Stockez-le sous forme de fichier texte, e. g. count-rows.awk, et appelez-le comme suit:

awk -f count-rows.awk -v needle=X input

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 pour needle sans échapper à des problèmes:

awk -f count-rows.awk -v needle="$needle" input
1
David Foerster