1

Consider the file shown below whose name is DRC.txt. The contents of the file are:

#############Actions#################
set a [project $p get_action ICV_DRC]
action $a set_parameter "ruledeck"
action $a set_parameter "options"

Now I have one variable called ruledeck = /praj/test/drc_tsn/test1. I need to append the value of this variable which is the path at the end of third line in the DRC.txt. I was trying to do it using sed, but the path is not added only the variable is. How can I solve the above problem?

sed -i -e '3s/$/"$ruledeck"/' DRC.txt

This command gives output as shown below:

#############Actions#################
set a [project $p get_action ICV_DRC]
action $a set_parameter "ruledeck" $ruledeck
action $a set_parameter "options"

I want output like this instead:

#############Actions#################
set a [project $p get_action ICV_DRC]
action $a set_parameter "ruledeck" /praj/test/drc_tsn/test1
action $a set_parameter "options"
3

There are two issues here. First, your sed command is in single quotes (''), so the variable isn't expanded:

$ echo $ruledeck 
/praj/test/drc_tsn/test1
$ echo '$ruledeck'
$ruledeck

I see you've put the variable in double quotes within the sed command, but that won't change anything since the entire thing is single quoted. You need to double quote it instead:

sed -e "3s/$/$ruledeck/" file

However, that will also break:

$ sed -e "3s/$/$ruledeck/" file
sed: -e expression #1, char 8: unknown option to `s'

This is because your variable contains /, but you are also using / as the delimiter for the substitution operator (s///). You need a different delimiter. This should do what you want:

$ sed -e "3s|$|$ruledeck|" file
#############Actions#################
set a [project $p get_action ICV_DRC]
action $a set_parameter "ruledeck"/praj/test/drc_tsn/test1
action $a set_parameter "options"

But that still isn't quite right if the line doesn't have a space in the end. To also add the space, but only if it isn't there already, use \? ( a space and an escaped question mark) to match "0 or 1 space". Putting all this together gives:

$ sed -e "3s| \?$| $ruledeck|" file
#############Actions#################
set a [project $p get_action ICV_DRC]
action $a set_parameter "ruledeck" /praj/test/drc_tsn/test1
action $a set_parameter "options"
10
  • The Last command which you mentioned is not giving the desire result which I want.
    – Lalitkumar
    Aug 22 '19 at 13:29
  • @Lalitkumar I can't help if you don't tell me what's wrong! It works exactly as I show on the example file you gave us. Is the value of $ruledeck as I show?
    – terdon
    Aug 22 '19 at 13:54
  • My guess: OP expects the -i flag and the filename DRC.txt...
    – Freddy
    Aug 22 '19 at 14:01
  • The value of $ruledeck which is the path is not appended at the end of 3rd in DRC.txt file by using this command- sed -e "3s| \?$| $ruledeck|" DRC.txt
    – Lalitkumar
    Aug 22 '19 at 18:03
  • @Lalitkumar but does it print the right output? Note that I'm not using -i, so the file won't be changed.
    – terdon
    Aug 22 '19 at 19:39
1

You can avoid any issues with quoting and regexp delimiters by using ed to append a line after line 3, and then join line 3 and the new line 4. e.g.

printf "%s\n" 3a " $ruledeck" . 3,4j  wq | ed -s DRC.txt

printf "%s\n" is used to pipe each of its remaining arguments to the text-editor ed, one at a time.

ex or vi -e (or vim -e or vim -E) could be used instead of ed - but note that ex and the various implementations of vi insert a space when joining lines, while ed does not (so the space at the beginning of the quoted string " $ruledeck" is not needed with those). They, along with sed and other related programs, all implement the same basic editing commands, with some mostly-minor differences, which originated with qed in 1965. Some also implement significant extensions to those commands.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.