135

I have a file that possibly contains bad formatting (in this case, the occurrence of the pattern \\backslash). I would like to use grep to return only the line numbers where this occurs (as in, the match was here, go to line # x and fix it).

However, there doesn't seem to be a way to print the line number (grep -n) and not the match or line itself.

I can use another regex to extract the line numbers, but I want to make sure grep cannot do it by itself. grep -no comes closest, I think, but still displays the match.

Neil
  • 1,578
  • 2
  • 10
  • 7
  • 2
    The most useful answer for me was in the question: `grep -no`! This did what I came here to try and do! (i.e. not print the line which is sometimes very long in, e.g., minified javascript source files.) – LondonRob Nov 12 '15 at 13:47

9 Answers9

205

try:

grep -n "text to find" file.ext | cut -f1 -d:
Ömer An
  • 600
  • 5
  • 16
love_me_some_linux
  • 2,661
  • 1
  • 15
  • 7
  • 1
    On my machine, this is only printing the matched files without line numbers (so if I have 3 matches inside a file it is only printed once) which is very useful still... – Mario Awad Nov 30 '12 at 12:17
  • 3
    @MarioAwad, you should manipulate `-f` param. For me it was `-f2`. (Know this is old stuff, but I think it could help some poor souls) – Emil Sierżęga Aug 27 '13 at 14:39
  • thanks for lovely old unix adhoc shell scripting. this shows that flexible tools are worth their complexity and learning curve! – Alexander Oh Dec 06 '13 at 08:44
  • 15
    `grep -n "text to find" file.ext | cut -f1,2 -d:` shows the file name and the line number. – Jondlm Jan 21 '14 at 20:50
  • 3
    @jondim it only shows the filename if there is more than one file being searched; you need to add `-H` to force it to show the filename when there is only one file. Conversely, you can always use `-h` to tell it not to output the filename no matter how many files you're grepping. – Mark Reed Sep 10 '17 at 14:55
55

If you're open to using AWK:

awk '/textstring/ {print FNR}' textfile

In this case, FNR is the line number. AWK is a great tool when you're looking at grep|cut, or any time you're looking to take grep output and manipulate it.

brightlancer
  • 2,059
  • 15
  • 7
52

All of these answers require grep to generate the entire matching lines, then pipe it to another program. If your lines are very long, it might be more efficient to use just sed to output the line numbers:

sed -n '/pattern/=' filename
maverick
  • 2,902
  • 2
  • 19
  • 15
2

Bash version

    lineno=$(grep -n "pattern" filename)
    lineno=${lineno%%:*}
maverick
  • 2,902
  • 2
  • 19
  • 15
2

I recommend the answers with sed and awk for just getting the line number, rather than using grep to get the entire matching line and then removing that from the output with cut or another tool. For completeness, you can also use Perl:

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

or Ruby:

ruby -ne 'puts $. if /pattern/' filename
Mark Reed
  • 91,912
  • 16
  • 138
  • 175
1

using only grep:

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

Micael Levi
  • 5,054
  • 2
  • 16
  • 27
0

You're going to want the second field after the colon, not the first.

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

Chris
  • 43
  • 2
  • This works if you want to matching text, but in the case the line number is what the OP was asking for. – AJP May 15 '13 at 22:12
0

To count the number of lines matched the pattern:

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

To extract matched pattern

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

To display line numbers on which pattern was matched

grep -n "pattern" file.ext | cut -f1 -d:
JstRoRR
  • 3,693
  • 2
  • 19
  • 20
  • 2
    1st should just be "grep -c 'Pattern' in_file.ext". 2nd should be "grep -o 'Pattern' in_file.ext". No need to involve sed or wc. – thelogix Nov 01 '14 at 18:12
0

bash:

readarray a <<< $(grep -n Pattern File)
echo ${a[@]%%:*}
for l in ${a[@]%%:*}

ksh93/bash(watchout lastpipe)

grep -n Pattern File | while IFS=: read l z
do echo $l
done
Phi
  • 735
  • 7
  • 22