Utilisez grep pour signaler uniquement les numéros de ligne


106

J'ai un fichier qui contient peut-être un mauvais formatage (dans ce cas, l'occurrence du motif \\backslash). Je voudrais utiliser greppour ne renvoyer que les numéros de ligne où cela se produit (comme dans, la correspondance était ici, allez à la ligne # x et corrigez-la).

Cependant, il ne semble pas y avoir de moyen d'imprimer le numéro de ligne ( grep -n) et non la correspondance ou la ligne elle-même.

Je peux utiliser un autre regex pour extraire les numéros de ligne, mais je veux m'assurer que grep ne peut pas le faire tout seul. grep -nose rapproche le plus, je pense, mais affiche toujours le match.


1
La réponse la plus utile pour moi était dans la question grep -no:! Cela a fait ce que je suis venu ici pour essayer de faire! (c'est-à-dire ne pas imprimer la ligne qui est parfois très longue, par exemple, dans les fichiers source javascript minifiés.)
LondonRob

Réponses:


156

essayer:

grep -n "text to find" file.ext | cut -f1 -d:

1
Sur ma machine, cela n'imprime que les fichiers correspondants sans numéros de ligne (donc si j'ai 3 correspondances dans un fichier, il n'est imprimé qu'une seule fois) ce qui est encore très utile ...
Mario Awad

3
@MarioAwad, vous devez manipuler -fparam. Pour moi, ça l'était -f2. (Sachez que c'est du vieux truc, mais je pense que cela pourrait aider certaines pauvres âmes)
Emil Sierżęga

merci pour le joli vieux script de shell adhoc unix. cela montre que les outils flexibles valent leur complexité et leur courbe d'apprentissage!
Alex

12
grep -n "text to find" file.ext | cut -f1,2 -d:affiche le nom du fichier et le numéro de ligne.
Jondlm

2
@jondim il montre uniquement le nom du fichier s'il y a plus d'un fichier recherché; vous devez ajouter -Hpour le forcer à afficher le nom de fichier lorsqu'il n'y a qu'un seul fichier. Inversement, vous pouvez toujours utiliser -hpour lui dire de ne pas afficher le nom de fichier, quel que soit le nombre de fichiers que vous greffe.
Mark Reed

45

Si vous êtes prêt à utiliser AWK:

awk '/textstring/ {print FNR}' textfile

Dans ce cas, FNR est le numéro de ligne. AWK est un excellent outil lorsque vous regardez grep | cut, ou chaque fois que vous cherchez à prendre une sortie grep et à la manipuler.


2
Utilise un processus (qui comptait plus dans le passé, mais quand même), et assez facile à comprendre pour les débutants awk!
bgStack15

NRfonctionne aussi bien lorsqu'il n'y a qu'un seul fichier en cours d'examen, comme dans ce cas.
Mark Reed

Tout simplement génial! C'est tellement rapide!
GTodorov le

34

Toutes ces réponses nécessitent grep pour générer toutes les lignes correspondantes, puis les diriger vers un autre programme. Si vos lignes sont très longues, il peut être plus efficace d'utiliser juste sed pour afficher les numéros de ligne:

sed -n '/pattern/=' filename

2

Version bash

    lineno=$(grep -n "pattern" filename)
    lineno=${lineno%%:*}

1
Et que se passe-t-il si plus d'une ligne correspond à ce modèle?
izabera

@izabera ajouter | tail -1
Diego

1

Je recommande les réponses avec sedet awkpour obtenir simplement le numéro de ligne, plutôt que d'utiliser greppour obtenir toute la ligne correspondante, puis de la supprimer de la sortie avec cutou un autre outil. Pour être complet, vous pouvez également utiliser Perl:

perl -nE '/pattern/ && say $.' filename

ou Ruby:

ruby -ne 'puts $. if /pattern/' filename

0

Vous allez vouloir le deuxième champ après les deux points, pas le premier.

grep -n "text to find" file.txt | cut -f2 -d:


Cela fonctionne si vous voulez faire correspondre le texte, mais dans le cas où le numéro de ligne est ce que l'OP demandait.
AJP

0

Pour compter le nombre de lignes correspondant au motif:

grep -n "Pattern" in_file.ext | wc -l 

Pour extraire le motif correspondant

sed -n '/pattern/p' file.est

Pour afficher les numéros de ligne sur lesquels le motif a été mis en correspondance

grep -n "pattern" file.ext | cut -f1 -d:

2
Le premier devrait être simplement "grep -c 'Pattern' in_file.ext". Le deuxième devrait être "grep -o 'Pattern' in_file.ext". Pas besoin d'impliquer sed ou wc.
thelogix

0

en utilisant uniquement grep :

grep -n "text to find" file.ext | grep -Po '^[^:]+'

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.