How to use a $sring in sed?

About writing shell scripts and making the most of your shell
Forum rules
Before you post please read how to get help
Post Reply
johngx
Level 1
Level 1
Posts: 25
Joined: Sun May 28, 2017 12:37 am

How to use a $sring in sed?

Post by johngx »

I have a gpx file to which I want to add text to a line between two patterns using a string.
TRIPNAME=Trip
echo $TRIPNAME
Trip
is there some way to add $TRIPNAME to a line between <name></name> using sed something like:
sed '/<name>"$TRIPNAME</name>\n' nnn.gpx
to create
<name>Trip</name>
or something else? (The above sed command has an error).
User avatar
xenopeek
Level 25
Level 25
Posts: 25607
Joined: Wed Jul 06, 2011 3:58 am
Location: The Netherlands

Re: How to use a $sring in sed?

Post by xenopeek »

This will do that:
sed -r "s|(<name>)(</name>)|\1$TRIPNAME\2|"

The \1 and \2 are backreferences to the () captured groups. Double quotes are needed so Bash will replace $TRIPNAME with its value. I use | (pipe character) as separator in the sed substitute command so I don't need to escape the forward slash in </name>.

In test it does as expected:

Code: Select all

$ TRIPNAME=Trip
$ echo '<name></name>' | sed -r "s|(<name>)(</name>)|\1$TRIPNAME\2|"
<name>Trip</name>
This matches it anywhere on a line, once. If you want to match it only at start of the line insert a ^ (caret character) after the first | (pipe character) to say it should match from the start of the line. If you want to replace all occurrences on a line add a g after the last | (pipe character).
Image
johngx
Level 1
Level 1
Posts: 25
Joined: Sun May 28, 2017 12:37 am

Re: How to use a $sring in sed?

Post by johngx »

Thank you xenopeek

That certainly works in a terminal

The question now is, how do I insert the output to file named test.gpx before the line <trkseg>

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="JGxxxxx">
-<trk>
  
  <trkseg>
   <trkpt lon="174.90728760" lat="-41.28062820">
    <ele>-102.724</ele>
    <time>2001-10-23T20:55:11.000Z</time>
   </trkpt>


'<name></name>' | sed -r "s|(<name>)(</name>)|\1$TRIPNAME\2|"
User avatar
xenopeek
Level 25
Level 25
Posts: 25607
Joined: Wed Jul 06, 2011 3:58 am
Location: The Netherlands

Re: How to use a $sring in sed?

Post by xenopeek »

I don't follow. I assume the lines you shared above is the file before modification. Can you show the same lines what they would be after your intended modification? So I can better understand.
Image
rene
Level 17
Level 17
Posts: 7766
Joined: Sun Mar 27, 2016 6:58 pm

Re: How to use a $sring in sed?

Post by rene »

Expect OP needs to add the entire <name>...</name> stanza rather than just add $TRIPNAME between an existing such one. If so sed's "i" operator will come in handy. E.g.

Code: Select all

rene@hp8k:~$ cat test.gpx 
<?xml version="1.0" encoding="UTF-8"?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="JGxxxxx">
-<trk>
  
  <trkseg>
   <trkpt lon="174.90728760" lat="-41.28062820">
    <ele>-102.724</ele>
    <time>2001-10-23T20:55:11.000Z</time>
   </trkpt>
rene@hp8k:~$ TRIPNAME=Trip
rene@hp8k:~$ sed "/<trkseg>/i\  <name>$TRIPNAME</name>" test.gpx
<?xml version="1.0" encoding="UTF-8"?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="JGxxxxx">
-<trk>
  
  <name>Trip</name>
  <trkseg>
   <trkpt lon="174.90728760" lat="-41.28062820">
    <ele>-102.724</ele>
    <time>2001-10-23T20:55:11.000Z</time>
   </trkpt>
You can of course redirect the output to a result file, or alternatively use sed -i instead to edit in this case "test.gpx" in-place.

[EDIT] Note; edited out a typo.
johngx
Level 1
Level 1
Posts: 25
Joined: Sun May 28, 2017 12:37 am

Re: How to use a $sring in sed?

Post by johngx »

Thank you rene, you correctly interpreted my poorly explained need. Your suggestion does just what I was looking for.
Post Reply