Problem getting Nth match in sed


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Problem getting Nth match in sed
# 1  
Old 07-21-2014
Problem getting Nth match in sed

Hi all,

I'm trying to create a sed command to get the Nth instance of an XML tag in a string, but thus far I can only ever seem to get the last one.

Given an XML string:
Code:
<Wrap><GrayLevel>a</GrayLevel><GrayLevel>b</GrayLevel></Wrap>

I tried to do this on the command line to get each GrayLevel (yes, I know it's messy, these were just the examples I was trying):

Code:
echo "<Wrap><GrayLevel>a</GrayLevel><GrayLevel>b</GrayLevel></Wrap>" | sed -e "s/.*<GrayLevel[^>]*>\(.*\)<\/GrayLevel>.*/\1/1"
echo "<Wrap><GrayLevel>a</GrayLevel><GrayLevel>b</GrayLevel></Wrap>" | sed -e "s/.*<GrayLevel[^>]*>\(.*\)<\/GrayLevel>.*/\1/2"

I expected to get the following from these examples:

Code:
a
b

But instead I got:

Code:
b
<Wrap><GrayLevel>a</GrayLevel><GrayLevel>b</GrayLevel></Wrap>

Can anyone explain to me what I'm doing wrong, please? I'm guessing it's something with the match parameter, but I can't figure out what.

Thanks,
Zel2008
# 2  
Old 07-21-2014
The problem is that the .* will match anything so there can only be one match per line (the last occurrence), so this is difficult with sed.

Perhaps you could try awk instead. For example:
Code:
awk -v n=1 '$1=="GrayLevel"{if(++c==n) print $2}' RS=\< FS=\>

Code:
awk -v n=2 '$1=="GrayLevel"{if(++c==n) print $2}' RS=\< FS=\>

# 3  
Old 07-21-2014
Thanks Scrutinizer,

I managed to find a solution in Perl:

Code:
perl -pe "s/(.*?<GrayLevel>){1}(.*?)<\/GrayLevel>.*/\2/"

That being said, I know absolutely nothing about awk. Would you mind explaining your awk solution in more detail, so I can learn what it does?

Thanks,
Zel2008
# 4  
Old 07-21-2014
Hi,
A sed solution (difference in red):
Code:
$ echo "<Wrap><GrayLevel>a</GrayLevel><GrayLevel>b</GrayLevel></Wrap>" | sed -e 's/<GrayLevel>\([^<]\+\)<\/GrayLevel>/xxx\1xxx/1;s/.*xxx\(.*\)xxx.*/\1/'
a
$ echo "<Wrap><GrayLevel>a</GrayLevel><GrayLevel>b</GrayLevel></Wrap>" | sed -e 's/<GrayLevel>\([^<]\+\)<\/GrayLevel>/xxx\1xxx/2;s/.*xxx\(.*\)xxx.*/\1/'
b

Regards.
This User Gave Thanks to disedorgue For This Post:
# 5  
Old 07-21-2014
Nice work-around disedorgue. One remark \+ is a GNU extension. Instead you could use the standard * , which would work just as well in this case. So ... \([^<]*\) ...
This User Gave Thanks to Scrutinizer For This Post:
# 6  
Old 08-06-2014
Hello,

Following may also help.

Code:
echo "<Wrap><GrayLevel>a</GrayLevel><GrayLevel>b</GrayLevel></Wrap>" | awk -F"[<>]" '{for(i=1;i<=NF;i++){if($i ~ /^[a-z]$/) {print $i}}}'

Output will be as follows.

Code:
a
b


Thanks,
R. Singh
# 7  
Old 08-06-2014
@Ravinder. That will only happen to work when the content is a single lowercase letter. I am sure that will be true for the example only. Besides it does not take the name of the label into consideration and it would list both labels and content if they are 1 lowercase letter wide..
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. AIX

Print nth previous line after match

Please help me print nth line after match awk or sed one line command. (3 Replies)
Discussion started by: sushma123
3 Replies

2. Shell Programming and Scripting

sed : replace Nth match in a file

I have a situation where a file "config.txt" looks like this Servername: OS: Serername: OS: Servername: OS: .... .... ... Servername: OS: looking for the sed syntax to replace the "Nth" occurrence of Servername (i would apply the same logic to OS as well), want to replace the Nth... (4 Replies)
Discussion started by: alldbest
4 Replies

3. Shell Programming and Scripting

How to display when nth line match a pattern?

Hi All, I have sample of listing as following Database 2 entry: Database alias = PXRES Database name = PXRES Local database directory = /db2/data1/db2phnx Database release level = d.00 Comment ... (3 Replies)
Discussion started by: ckwan
3 Replies

4. UNIX for Dummies Questions & Answers

Printing nth and n+1th line after a pattern match

Hi , I want to print the nth and n+1 lines from a file once it gets a pattern match. For eg: aaa bbb ccc ddd gh jjjj If I find a match for bbb then I need to print bbb as well as 3rd and 4th line from the match.. Please help..Is it possible to get a command using sed :) (6 Replies)
Discussion started by: saj
6 Replies

5. Shell Programming and Scripting

problem using sed to match a string

Hi There! I'm stuck with a problem trying to output some sections of a rss feed to my conky program using curl and sed. The rss feed is for tide times and I wish to output the times but not the rest to the conky desktop. To do this I need to pull out the four instances of times that are in... (4 Replies)
Discussion started by: huffpuff
4 Replies

6. Shell Programming and Scripting

search pattern and replace x-y characters in nth line after every match

Hi, I am looking for any script which can do the following. have to read a pattern from fileA and copy it to fileB. fileA: ... ... Header ... ... ..p1 ... ... fileB: .... .... Header (3 Replies)
Discussion started by: anilvk
3 Replies

7. UNIX for Dummies Questions & Answers

finding the nth match

I have a file that has information for a person....each person gets 3 or more lines to describe them. I was hoping to match person 1, then person 2.....BUT I do not know how to tell grep I only want the first (2nd, 3rd or nth) match. The alternative is doing line by line logic, which is fine... (8 Replies)
Discussion started by: countryStyle
8 Replies

8. Shell Programming and Scripting

sed pattern match problem

Hi all, hoping this is a simple one, tried looking but just can't see the solution As an example I've got a list of words that all start Ben..... Bendicks Benefiber Ben Benylin I need to only change the line Ben with Ben 10, ignoring the other lines. I tried the following ... (1 Reply)
Discussion started by: mrpugster
1 Replies

9. Shell Programming and Scripting

Getting filename for Nth line pattern match

Hi, I have many scripts in particular directory. And few of the scripts have exit 0 in second line. Now i wanted to list out the scripts name which has the exit 0 in its second line I tried many options , but i can not get the filename along with the nth line pattern match :mad:. Can anyone... (14 Replies)
Discussion started by: puni
14 Replies

10. Shell Programming and Scripting

sed problem - delete all lines until a match on 2 lines

First of all, I know this can be more eassily done with perl or other scripting languages but, that's not the issue. I need this in sed. (or wander if it's possible ) I got a file (trace file to recreate the control file from oracle for the dba boys) which contains some lines another line... (11 Replies)
Discussion started by: plelie2
11 Replies
Login or Register to Ask a Question