LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-13-2006, 07:39 AM   #1
judgex
LQ Newbie
 
Registered: Jan 2006
Location: Australia
Distribution: Fedora Core 4 and Cygwin
Posts: 14

Rep: Reputation: 0
Grep's line numbers parsed into one line of output.


Code:
echo `grep -n foo bar.txt | cut -d: -f1` | tr ' ' :
The -n option to grep prefixes each match with a corresponding line number. The cut gets rid of the matches, giving a list of numbers. The echo converts the newlines into spaces, except for the last newline which is removed. Finally tr is used to convert spaces into colons.

If bar.txt contains foo on lines 15, 16, 21 and 26, the final output will be 15:16:21:26.

Can anyone show me a simpler way of doing this?

Thanks in advance.
 
Old 08-13-2006, 08:59 AM   #2
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405
Hi,

If a : at the end of a line is no problem, you can do this with one command:

awk '/foo/ { printf FNR ":" } END { print"" }' bar.txt

Your output will look like this:

15:16:21:26:

Don't know if you have any experience with AWK, so here's a little breakdown:
/foo/ => looks for lines with foo in them, if that is the case:
printf FNR ":" => print the linenumber (FNR) followed by a : (no newline, that's why printf is used instead of print)
The print"" in the END section prints a newline.

But, like I stated before, there will be an extra : at the end.

Hope this helps.
 
Old 08-13-2006, 10:01 AM   #3
judgex
LQ Newbie
 
Registered: Jan 2006
Location: Australia
Distribution: Fedora Core 4 and Cygwin
Posts: 14

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by druuna
Hi,

If a : at the end of a line is no problem, you can do this with one command:

awk '/foo/ { printf FNR ":" } END { print"" }' bar.txt

Your output will look like this:

15:16:21:26:

Don't know if you have any experience with AWK, so here's a little breakdown:
/foo/ => looks for lines with foo in them, if that is the case:
printf FNR ":" => print the linenumber (FNR) followed by a : (no newline, that's why printf is used instead of print)
The print"" in the END section prints a newline.

But, like I stated before, there will be an extra : at the end.

Hope this helps.
I like that method. I can get rid of the last colon using:
Code:
awk '/foo/ { printf ":" FNR }' bar.txt | cut -c2-
Thanks for your help.
 
Old 08-13-2006, 10:19 AM   #4
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405
Hi,

Yes, getting rid of the last colon isn't hard, but do you really need to?

Starting a shell is one of the more resource intensive actions, when piping something to something else (awk ... | cut ...) you need a shell for all the commands (2 in this example. The first example you gave needs 3 shells) and pipes between them have to be set up.

It sometimes is wiser to leave the output the way it is, depending on what you are going to do next.
 
Old 08-13-2006, 12:54 PM   #5
burninGpi
Member
 
Registered: Mar 2006
Location: Fort McMurray, Canada
Distribution: Gentoo ~amd64
Posts: 163

Rep: Reputation: 30
awk '/foo/{print FNR ":"}' will result in:
15:
16:
21:
26:
...

to solve all the problems:
Code:
awk 'BEGIN{ORS="";first=1}/foo/{if (first==1){first=0;print FNR}else{print ":" FNR}}END{print "\n"}' bar.txt
If you want to search for just the word foo, and not food or afoo, you need to use
Code:
awk 'BEGIN{ORS="";first=1}
/([^[:alnum]]|^)foo([^[:alnum:]]|$)/
{if (first==1){first=0;print FNR}else{print ":" FNR}}
END{print"\n"}' bar.txt
and to match foo case-insensitivitely, replace foo in the RE (between the slashes) with [Ff][Oo][Oo]

Last edited by burninGpi; 08-13-2006 at 02:32 PM.
 
Old 08-13-2006, 06:34 PM   #6
judgex
LQ Newbie
 
Registered: Jan 2006
Location: Australia
Distribution: Fedora Core 4 and Cygwin
Posts: 14

Original Poster
Rep: Reputation: 0
Thank you Burnin. Those commands do everything I need.

Druuna, I'm not sure if I really need to remove the last colon.

Last edited by judgex; 08-13-2006 at 06:36 PM.
 
Old 08-14-2006, 03:54 AM   #7
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405
Hi,

burninGpi already did the extra awk work, go for that example. It's complete, resource friendly and basically elegant
 
Old 08-14-2006, 04:10 AM   #8
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: Mint, Armbian, NetBSD, Puppy, Raspbian
Posts: 3,515

Rep: Reputation: 239Reputation: 239Reputation: 239
Code:
grep -n foo bar.txt| cut -f1 -d: | xargs
Code:
 perl -ne 'print "$. " if /foo/' bar.txt
 
Old 08-14-2006, 04:22 AM   #9
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405
Hi,

The perl code snippet has the same pitfall as my command: It will print a charachter (a space in your perl example) after the last found entry.

burninGpi's example still seems to be the only one-liner that works without extra pipe(s).
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
printing line numbers for code bauer172uw Programming 3 04-13-2006 11:10 PM
Prepend # for certain line numbers in VI twantrd Linux - Software 3 09-05-2005 01:27 PM
Command to output file content line by line aznluvsmc Programming 2 09-12-2004 07:45 PM
printing line numbers? fisheromen1031 Programming 1 07-27-2004 02:19 PM
line numbers in kdevelop febisfebi Programming 1 02-18-2004 07:45 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:42 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration