sed - use back reference in 2nd command


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting sed - use back reference in 2nd command
# 1  
Old 08-07-2017
sed - use back reference in 2nd command

I have data that looks like this:
Code:
<Country code="US"><tag>adsf</tag><tag>bdfs</tag></Country><Country code="CA"><tag>asdf</tag><tag>bsdf</tag></Country>

I want to grab the country code save it, then drop each new "<..." onto a new line with the country code added to the beginning of each
So, the above would become:
Country - US
US asdf
US bsdf
US csdf
Country - CA
CA asdf
CA bsdf
CA csdf

I do this:
 sed 's/<Country code="\(..\)">/<Country - \1>/g;s/</\n&/g' inputfile.txt | grep Country
<Country - US>
</Country>
<Country - CA>
</Country>

But, if I try to add a reference to \1 to the second substitution, I get an error :
Code:
sed 's/<Country code="\(..\)">/<Country - \1>/g;s/</\n\1&/g' inputfile.txt | grep Country
sed: -e expression #1, char 54: invalid reference \1 on `s' command's RHS

ideas?
# 2  
Old 08-07-2017
Quote:
Originally Posted by JenniferAmon
I want to grab the country code save it, then drop each new "<..." onto a new line with the country code added to the beginning of each
What you need is not a (non-persistent) backreference but the (persistent) "hold space": this is a space where you can add, copy or pull text out of. I suggest you read the man page of sed to make yourself acquainted with the concept.

You best start by thinking through what you need to do for every type of line, i.e.:

a) lines with "country=" in them: load hold space with country code
b) all lines:
b1) split into tags (starting with "<")
b2) remove the tags themselves (as i took it from your sample output)
b3) add the content of the hold space to the begin of the pattern space

Note that you make your life a lot easier by using multi-line sed-programs. In principle you can the above also in a one-liner - like you can write a C program into one line too - but it would be very hard to read, even harder to understand and nigh impossible to debug.

I hope this helps.

bakunin
# 3  
Old 08-07-2017
Code:
sed 's/</\n</g' input_file | awk '
/<Country .*code=/ {
   country=$0;
   sub(".*code=\"*", "", country);
   sub("\".*", "", country);
   c=$0;
   sub(" .*", "", c);
   sub("< *", "", c);
   print c " - " country;
   next;
}
/<[^\/]*>/ {
   tag=$0;
   sub("<[^>]*> *", "", tag);
   print 1,country, 1,tag;
}
'

# 4  
Old 08-07-2017
The 2nd s resets the references.
It only works if its search pattern is empty i.e. taken from a previous match - but how to get a g option from a match?
The following works with one s but the number of <tag>s must be static, e.g. 2.
Code:
sed 's#<Country code="\(..\)"><tag>\([^<]*\)</tag><tag>\([^<]*\)</tag></Country>#Country - \1\
\1 \2\
\1 \3\
#g' inputfile.txt


Last edited by MadeInGermany; 08-07-2017 at 05:45 PM..
# 5  
Old 08-07-2017
Hi
With awk
Code:
awk 'BEGIN{FS="[><]";RS="<Country code="}/^$/{next};{gsub("\"","",$1);print "Country - "$1"\n"$1" "$4"\n"$1" "$8 }' inputfile

# 6  
Old 08-08-2017
And another one that works like the previous suggestions.
Code:
sed 's/</\
/g' inputfile.txt | sed '
\#^Country code="\(.*\)".*#{s##\1#;h;}
\#^tag>#!d
G;s#^tag>\(.*\)\n\(.*\)#\2 \1#
'

Because the first sed splits into lines, the second sed can take any number of <tag>s. Also it will tolarate(discard) other stuff in between (for example a <b> tag).
A Countr= header is left as an exercise.
# 7  
Old 08-08-2017
Try also
Code:
sed 's/<Country code="\(..\)">/\nCountry - \1/g; s/^\n//; s|</[^>]*>||g; s/<[^>]*>/\n/g' file | sed '/Country - / {p; s///; x; d}; G; s/\(.*\)\n\(.*\)/\2 \1/'
Country - US
US adsf
US bdfs
Country - CA
CA asdf
CA bsdf


Last edited by RudiC; 08-08-2017 at 09:04 AM..
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. UNIX for Dummies Questions & Answers

Extract text in sed using back reference

i have a text 20 21 22 23 24 25 26 i want to get 22 using sed back reference. I have used sed 's/{6}\(..\).*/\1/' but, it does not work. I am missing something somewhere. Please help. (5 Replies)
Discussion started by: gotamp
5 Replies

2. Shell Programming and Scripting

sed back reference error

I am trying to change a single line of a special file whose comment character is ! to show a path to the file in the comment. such as: !!HFSS and mcm path: \Signal_Integrity\Package_SI\Section_Models\C4toTrace\28nm\D6HS\SLC_5-2-5\GZ41_ICZ\NSSS\ to a different path and replace the !!HFSS... (1 Reply)
Discussion started by: mobrien601
1 Replies

3. UNIX for Dummies Questions & Answers

Invalid back reference

The thread can be closed now :D. (3 Replies)
Discussion started by: vaz0r
3 Replies

4. Shell Programming and Scripting

sed error: invalid reference

Hello all, I am using sed to parse a particular part of a string and am having problems. I am getting the following error: sed: -e expression #1, char 28: invalid reference \1 on `s' command's RHS Here is the code I am using: echo "Alarm SET:" echo "" echo "Date: " $DATE echo... (4 Replies)
Discussion started by: dlundwall
4 Replies

5. Shell Programming and Scripting

Shell Scripting Problem - Invalid Back Reference

Here is the question... Create a new script, sub2, taking three parameters... 1.) the string to be replaced 2.) the string with which to replace it 3.) the name of the file in which to make the substitution ...that treats the string to be replaced as plain text instead of as a regular... (1 Reply)
Discussion started by: johnhisenburg
1 Replies

6. Shell Programming and Scripting

Perl: Getting back reference from s modifier

My input text has the following pattens: func_a(3, 4, 5); I want to replace it with this: func_b(3, 4, 5, 6); I'm trying the following expression, but it does not work: perl -p -e "s/func_a\((.*)?\);/func_b(\1,\n6)/s" <... (8 Replies)
Discussion started by: cooldude
8 Replies

7. Shell Programming and Scripting

How to reference a variable within sed?

Hi all, How can I use sed to perform a substitution if the string that I'm going to substitute is stored in a variable: Let's say: sed 's/abcdefg/good' VS tmp="abcdefg" sed 's/$tmp/good' The second case doesn't work. Guess it's due to the single quotes on the outside. How can I... (1 Reply)
Discussion started by: rockysfr
1 Replies

8. Shell Programming and Scripting

sed command to change 2nd field

Hi I am a beginner to sed command, here I have a question about using sed to add a few characters into a token of a string. For example, I have a file, sqw:qqq:123124:uiqe dfd:ccc:12390:dfjis cde:aaa:21311:dfjsid and, I want the output to be, sqw:qqq:123124:uiqe... (4 Replies)
Discussion started by: Julius
4 Replies

9. Shell Programming and Scripting

back reference error

Hi, i am getting this error........ find ./ | sed '/\(*\) \(*\)/\2\1/' Unrecognized command: /\(*\) \(*\)/\2\1/ Any idea??? regards Apoorva Kumar (4 Replies)
Discussion started by: apoorvasharma80
4 Replies

10. UNIX for Dummies Questions & Answers

sed command for using with back slashes

hi all, im trying to use a sed command to remove all occurenes of \p\g what i used so far is : sed 's!\p\g!!g' file but this doesnt work ? Any ideas, thanks for helping. (2 Replies)
Discussion started by: seaten
2 Replies
Login or Register to Ask a Question