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.

Neil
la source
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:
love_me_some_linux
la source
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.

brillant
la source
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
Maverick
la source
2

Version bash

    lineno=$(grep -n "pattern" filename)
    lineno=${lineno%%:*}
Maverick
la source
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
Mark Reed
la source
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:

Chris
la source
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:
JstRoRR
la source
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 '^[^:]+'

Micael Levi
la source