LinuxQuestions.org
Review your favorite Linux distribution.
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 05-08-2007, 03:35 PM   #1
jong357
Senior Member
 
Registered: May 2003
Location: Columbus, OH
Distribution: DIYSlackware
Posts: 1,914

Rep: Reputation: 52
sed problem...


Hey all. I need a certain line to be printed from a file but am having troubles.

Code:
foo
bar
foo
bar
foo
bar
bar
bar
I need to print bar that comes after the last foo found. I'm trying to take baby steps and just change the last occurance of foo to foomark, but I can't get that far.

Code:
sed 's/\(.*\)foo/\1foomark/' test
After looking around on the web, the above command is _supposed_ to change the last occurance of foo but it changes all the foo's. If someone want's to point me in the right direction, that would be great. Better yet, how can I just print bar after the last foo found?

Last edited by jong357; 05-08-2007 at 03:48 PM.
 
Old 05-08-2007, 04:39 PM   #2
nmh+linuxquestions.o
Member
 
Registered: Feb 2007
Posts: 135

Rep: Reputation: 15
Sed usually works on one line at a time - replacing the first or last instance of a pattern means the first or last on each line of input.
 
Old 05-08-2007, 04:52 PM   #3
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Arch/XFCE
Posts: 17,802

Rep: Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728
to know that it has found the last "foo", it has to go the end of the file. In addition, it has to remember where the last "foo" was, and then print the next line.

It seems like you will need a loop, with something like awk (gawk) reading one line at a time and with a counter tracking line numbers. When the loop exits, it can return the line number of the last "foo". Then increment this and use it to get the line you want.
 
Old 05-08-2007, 05:06 PM   #4
jong357
Senior Member
 
Registered: May 2003
Location: Columbus, OH
Distribution: DIYSlackware
Posts: 1,914

Original Poster
Rep: Reputation: 52
Oh.. I must have misunderstood then. Hmm... I also thought awk would be better able to handle it.

I'll go ahead and post this because it's directly related to my problem. The reason I'm looking to use sed or something similar is because the below code doesn't tranfer my variable. I'm using a logging function to redirect output but I need my variable from blah2 to stick when I call blah1 (which actually checks PIPESTATUS to see if we are done or an error occured).

This is a "borrowed" logging facility, thus I don't quite understand how to restructure calling on blah2 so it'll export my variable yet retain it's functionality...

Code:
#!/bin/sh

blah1()
{
echo $variable
}

blah2()
{
variable=printme
}

{ blah2 3>&1 1>&2 2>&3 | tee "blah.err";} &>"blah.log"
#blah2
blah1

Last edited by jong357; 05-08-2007 at 05:11 PM.
 
Old 05-08-2007, 08:48 PM   #5
makyo
Member
 
Registered: Aug 2006
Location: Saint Paul, MN, USA
Distribution: {Free,Open}BSD, CentOS, Debian, Fedora, Solaris, SuSE
Posts: 718

Rep: Reputation: 72
Hi.
Quote:
Originally Posted by jong357
I need to print bar that comes after the last foo found.
Sometimes old tools come in handy. The editor ed can go backwards, so if we have ed go to the last line, then search backwards for foo, then print from there to bar, we should have it. I added line numbers to your test file to show how it works.
Code:
#!/bin/sh

# @(#) s2       Demonstrate interactive editor ed script.

echo " Original file data1:"
cat data1

echo
echo " Running ed:"
ed data1 <<EOF
$
=
?foo
.,/bar/w data2
q
EOF

echo
echo " File data2:"
cat data2

exit 0
Producing:
Code:
% ./s2
 Original file data1:
foo 1
bar 2
foo 3
bar 4
foo 5
bar 6
bar 7
bar 8

 Running ed:
48
bar 8
8
foo 5
12

 File data2:
foo 5
bar 6
cheers, makyo
 
Old 05-08-2007, 09:10 PM   #6
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,695
Blog Entries: 5

Rep: Reputation: 241Reputation: 241Reputation: 241
here's an awk one, i don't know what you want to do after you found the first bar after foo, so i break it out.

Code:
awk ' /foo/ { c=NR; }
 {arr[NR]=$0 }
 END {  
	for ( i = c; i<=NR; i++ ) {
		if  ( arr[i] == "bar" ) {
			print arr[i],i
			break
		}
	}
 }' "file"

Last edited by ghostdog74; 05-08-2007 at 09:14 PM.
 
Old 05-08-2007, 11:16 PM   #7
jong357
Senior Member
 
Registered: May 2003
Location: Columbus, OH
Distribution: DIYSlackware
Posts: 1,914

Original Poster
Rep: Reputation: 52
Thanks guys for the help.. The more I think about it, the more I realize this isn't the way to go. My script is small and compact and I really don't wan't to clutter it up by adding lot's of stuff for this one thing.

Going upstream to the source, my problem lies in the below script by having brackets wrapped around my function call.

This whole sed/ed/awk stuff is just to try and come up with $variable.... Which is already defined in 'blah2'. So...... If I can't figure out how to get this to work by modifying my blah2 call, then I'll just throw in the towel I suppose... Bummer. I do appreciate the help tremendously tho... As you can see, if you run this script, $variable doesn't get outputted... I do need to retain my redirects but the .err file is useless and could stand to go away.

So.. In short. echo $variable from blah1 while still silencing/redirecting output from blah2...
Code:
#!/bin/sh

blah1()
{
echo $variable
}

blah2()
{
variable=printme
}

{ blah2 3>&1 1>&2 2>&3 | tee "blah.err";} &>"blah.log"
#blah2
blah1
 
Old 05-08-2007, 11:30 PM   #8
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,695
Blog Entries: 5

Rep: Reputation: 241Reputation: 241Reputation: 241
Quote:
Originally Posted by jong357
Thanks guys for the help.. The more I think about it, the more I realize this isn't the way to go. My script is small and compact and I really don't wan't to clutter it up by adding lot's of stuff for this one thing.

Going upstream to the source, my problem lies in the below script by having brackets wrapped around my function call.

This whole sed/ed/awk stuff is just to try and come up with $variable.... Which is already defined in 'blah2'. So...... If I can't figure out how to get this to work by modifying my blah2 call, then I'll just throw in the towel I suppose... Bummer. I do appreciate the help tremendously tho... As you can see, if you run this script, $variable doesn't get outputted... I do need to retain my redirects but the .err file is useless and could stand to go away.

So.. In short. echo $variable from blah1 while still silencing/redirecting output from blah2...
Code:
#!/bin/sh

blah1()
{
echo $variable
}

blah2()
{
variable=printme
}

{ blah2 3>&1 1>&2 2>&3 | tee "blah.err";} &>"blah.log"
#blah2
blah1

somehow, you have to "return" the "variable" in blah2 back to the main script.
one way to do this is :
Code:
..
variable=printme
echo $variable
}
 
Old 05-08-2007, 11:44 PM   #9
jong357
Senior Member
 
Registered: May 2003
Location: Columbus, OH
Distribution: DIYSlackware
Posts: 1,914

Original Poster
Rep: Reputation: 52
No that's not working.. Good idea tho.. I see what your saying.. What sort of confuses me is, that if you comment my blah2 call with the redirects and then just call it straight out, it works..
 
Old 05-09-2007, 12:08 AM   #10
jong357
Senior Member
 
Registered: May 2003
Location: Columbus, OH
Distribution: DIYSlackware
Posts: 1,914

Original Poster
Rep: Reputation: 52
Code:
#!/bin/sh

blah1()
{
echo ${variable}-new
}

blah2()
{
variable=printme
}

{ blah2 && export $variable 3>&1 1>&2 2>&3 | tee "blah.err";} &>"blah.log"
blah1
That works... However... It ruins my error checking from within blah1... Not good.
Code:
blah1()
{
   for i in "${PIPESTATUS[@]}"
   do
     test $i != 0 && { echo $variable ; exit 1 ; }
   done
   echo "Successful!"
   return 0
}
I have another idea that's pretty hackish. We'll see. Thanks for getting the ball rolling!!!

EDIT: Ughhhh.. Something wierd is going on.. My test script works but my actuall build script doesn't...

test.sh
Code:
#!/bin/sh

blah1()
{
   for i in "${PIPESTATUS[@]}"
   do
     test $i != 0 && { echo $variable ; exit 1 ; }
   done
   echo "Successful!"
   return 0
}

blah2()
{
variable=Failed
mv ficticious ficticious.null
}

{ blah2 && export $variable 3>&1 1>&2 2>&3 | tee "blah.err";} &>"blah.log"
blah1

Last edited by jong357; 05-09-2007 at 12:13 AM.
 
Old 05-09-2007, 12:16 AM   #11
igorc
Member
 
Registered: May 2005
Location: Sydney, Australia
Distribution: Ubuntu 5.04, Debian 3.1
Posts: 74

Rep: Reputation: 15
Hi,

# sed -n '/foo/{n;p;}' somefile.txt | tail -1

exp: sed command gives you every first line after every foo and with tail you get the last one which is the one you want.

Cheers,
 
Old 05-09-2007, 12:27 AM   #12
jong357
Senior Member
 
Registered: May 2003
Location: Columbus, OH
Distribution: DIYSlackware
Posts: 1,914

Original Poster
Rep: Reputation: 52
Quote:
Originally Posted by igorc
sed -n '/foo/{n;p;}' somefile.txt | tail -1
Nice... Exactally what I was after. A one-liner that's not obtrusive on my script. The output from that line contains $variable but I'll still need to pipe it to a couple sed -e to isolate $variable..

It's too bad I had to start messing around and get obsessed with my above post... I'll tuck that sed away and use it when I'm utterly fed up with trying to figure out why my script doesn't work but the test case does...

Thanks guys for your help. It's very appreciated.

Last edited by jong357; 05-09-2007 at 12:33 AM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
sed problem Hydrap Linux - General 3 03-30-2006 07:31 AM
Sed problem twintornado Programming 2 06-02-2005 08:25 AM
sed problem Warmduvet Programming 2 09-15-2004 06:33 PM
Help Sed Problem anirudh Linux User Groups (LUG) 1 08-30-2004 02:25 PM
Insert character into a line with sed? & variables in sed? jago25_98 Programming 5 03-11-2004 06:12 AM


All times are GMT -5. The time now is 07:24 AM.

Main Menu
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
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration