Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

sed with bash variable

Posted on 2003-12-04
19
Medium Priority
?
1,831 Views
Last Modified: 2008-01-09
Dear all.

A little bit stuck here using sed in a bash script.

I want to change a single line in a file, e.g
---------
...
PREFIX=/usr/lib
...
---------

to become
---------
...
PREFIX=/usr/X11R6
...
---------

I can do that from command line

$ sed -e `s/^PREFIX=.*/PREFIX=\/usr\/X11R6`  the_file

But I got difficulty to do that in a bash script,
when the substituter is a variable.

#/bin/sh
PREFIX=/usr/X11R6
THEFILE=the_file

# How to call sed to change PREFIX=anything to PREFIX=$PREFIX here ?

# these did not work
sed -e `s/PREFIX=.*/$PREFIX` $THEFILE
sed -e "s/PREFIX=.*/$PREFIX" $THEFILE


Thanks
0
Comment
Question by:Kocil
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 5
  • 2
  • +2
19 Comments
 
LVL 24

Expert Comment

by:shivsa
ID: 9876028
cat $i | sed 's/'$pattern'/'$replacement'/g' > $j
check this post.
http://www.experts-exchange.com/Programming/Programming_Platforms/Linux_Programming/Q_20239657.html
0
 
LVL 24

Expert Comment

by:shivsa
ID: 9876055
or try this

PREFIX = `echo $PREFIX |sed "s/lib/X11R6/"`
0
 
LVL 5

Author Comment

by:Kocil
ID: 9876481
>> cat $i | sed 's/'$pattern'/'$replacement'/g' > $j

It does not work, error:
sed: -e expression #1, char 12: Unknown option to `s'



0
Quick Cloud Training

Looking for some quick training on the cloud in 2 hours or less? Check out these how-to guides in AWS, Linux, OpenStack, Azure, and more!

 
LVL 5

Author Comment

by:Kocil
ID: 9876562
Uh ... it works for:

PREFIX=anything
cat the_file | sed 's/PREFIX=.*/'$PREFIX'/g' > $the_file

does not works for:
PREFIX=/usr/lib
cat the_file | sed 's/PREFIX=.*/'$PREFIX'/g' > $the_file

hmmm ???
I guess the '/' is the problem. How to fix that ?
0
 
LVL 24

Expert Comment

by:shivsa
ID: 9876574
PREFIX=`echo $PREFIX |sed "s/lib/X11R6/"`

this is working perfectly on my system.
0
 
LVL 5

Author Comment

by:Kocil
ID: 9876575
I meant
cat $the_file | sed 's/PREFIX=.*/'$PREFIX'/g' > $the_file
0
 
LVL 5

Author Comment

by:Kocil
ID: 9876596
> PREFIX=`echo $PREFIX |sed "s/lib/X11R6/"`

Yeah. If the replacement does not contain /, it works.
Unfortunatelly, my case contains / most of the time


0
 
LVL 24

Expert Comment

by:shivsa
ID: 9876696
try putting " " around the variable.
cat $the_file | sed 's/PREFIX=.*/"$PREFIX"/g' > $the_file
0
 
LVL 5

Author Comment

by:Kocil
ID: 9876834
I tried ...

$ PREFIX=/usr/lib

$ echo $PREFIX
/usr/lib

$ echo "PREFIX=xxx" | sed 's/PREFIX=.*/PREFIX="$PREFIX"/g'
PREFIX="$PREFIX"

still not working :)

0
 
LVL 7

Expert Comment

by:glassd
ID: 9876989
So you need to change one line in a file. Sed will not write back to the source file so you need to use a temp file:

From="/usr/lib"
To="/usr/X11R6"

sed -e ":^PREFIX=:s:$From:$To:" infile > tempfile
cp tempfile infile
rm tempfile

Using the colon as the field separator in sed avoids all the problems caused by the slash contained in the variable.
0
 
LVL 24

Expert Comment

by:shivsa
ID: 9876990
u can use your own string into this and work it out.

PREFIX=`echo $PREFIX |sed "s/\/usr\/lib/\/usr\/X11R6/"`
echo $PREFIX
/usr/X11R6
0
 
LVL 5

Author Comment

by:Kocil
ID: 9877373
>> sed -e ":^PREFIX=:s:$From:$To:" infile > tempfile

I don't understand the syntax. I copied it as is, but it did not work on an infile containing

AAAA
PREFIX=/usr/lib
BBBB

0
 
LVL 5

Author Comment

by:Kocil
ID: 9877429
>> PREFIX=`echo $PREFIX |sed "s/\/usr\/lib/\/usr\/X11R6/"`

Yes, so the problem is I have to convert "/usr/X11R6" to "\/usr\/X11R6".

ah ... I got it

PREFIXED=`echo $PREFIX | sed -e 's/[\/]/\\///g'`
cat $the_file | sed -e 's/^PREFIX=.*/PREFIX='$PREFIXED'/g' > $the_file

It solved now,
But I'm interested on glassd's slash-trouble free solution and waiting for his responds.







0
 
LVL 7

Assisted Solution

by:glassd
glassd earned 200 total points
ID: 9878368
Sorry, untested code. Dodgy syntax. This should work:

Assuming the input file:

   AAAA
   PREFIX=/usr/lib
   Prefix=/usr/lib
   BBBB

Then running the script:

   From="/usr/lib"
   To="/usr/X11R6"
   sed -e "/^PREFIX=/s:$From:$To:" infile

should return:

   AAAA
   PREFIX=/usr/X11R6
   Prefix=/usr/lib
   BBBB

The first part (/^PREFIX=/) finds all lines beginning with "PREFIX=" (the "^" character represents the beginning of the line). This pattern must be enclosed in "/" characters (my mistake there).

Then you can use whatever character you like as the separator. A colon is common as it does not normally appear in file names.

The rest of the line substitutes any occurance of "/usr/lib" (held in the variable $From) with "/usr/X11R6" (held in the variable $To).

So the sed command should change "/usr/lib" to "/usr/X11R6" on any line starting "PREFIX=".

Does all that make sense? Not too sure!
0
 
LVL 45

Accepted Solution

by:
sunnycoder earned 600 total points
ID: 9880556
abc=/a/b/c
sed -e "s:^PREFIX=.*:PREFIX=$abc:" test.txt

worked for me
0
 
LVL 51

Assisted Solution

by:ahoffmann
ahoffmann earned 200 total points
ID: 9889906
doh, to much comments to read carefully ..
sound like / problem, see glassd and sunnycoder's suggestions to

 cat $the_file | sed 's#PREFIX=.*#'$PREFIX'#g' > $the_file
0
 
LVL 5

Author Comment

by:Kocil
ID: 9893861
>> sed -e "s:^PREFIX=.*:PREFIX=$abc:" test.txt
EXCELLENT

>> cat $the_file | sed 's#PREFIX=.*#'$PREFIX'#g' > $the_file
works too

>> sed -e "/^PREFIX=/s:$From:$To:" infile
works too

I split the point.
Thanks all.
0
 
LVL 5

Author Comment

by:Kocil
ID: 9893871
The lesson I learnt .... we can use : and # as a separator.
They should document it in an easier place :)
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 9895216
> The lesson I learnt .... we can use ..
.. any (printable) character as separator ;-)
0

Featured Post

Veeam Task Manager for Hyper-V

Task Manager for Hyper-V provides critical information that allows you to monitor Hyper-V performance by displaying real-time views of CPU and memory at the individual VM-level, so you can quickly identify which VMs are using host resources.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever been frustrated by having to click seven times in order to retrieve a small bit of information from the web, always the same seven clicks, scrolling down and down until you reach your target? When you know the benefits of the command l…
The purpose of this article is to fix the unknown display problem in Linux Mint operating system. After installing the OS if you see Display monitor is not recognized then we can install "MESA" utilities to fix this problem or we can install additio…
This course is ideal for IT System Administrators working with VMware vSphere and its associated products in their company infrastructure. This course teaches you how to install and maintain this virtualization technology to store data, prevent vuln…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…

721 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question