1

I know this question has probably been answered before. I have seen many threads about this in various places, but the answers are not working for me. I am looking for help with an example usage of the 'sed' command.

What I am trying to do is reading some strings from a file and then using those values to replace the strings of few other files

Example:

File1.txt

name:
abcd

age:
22

File2.xml

<root>
 <name>xxxx</name>
 <age>xxxx</age>
</root>

I am reading name and age from file 1 and trying to replace missing values in the file 2. I have tried to use hard coding and replacing the values in a file :

$name=abcd
$age=22

sed -e 's/.*<name>\([^<]*\)</name>.*/${name}/g' file2.xml

Note: it is not possible to use sed -i. Old version I guess

for the above script I am getting an error

sed: 0602-404 Function s/.*<name>\([^<]*\)</name>.*/${name}/g cannot be parsed.

so first of all I'd like a script to read from the file and then a script to write in to a file without creating a new file.

UPDATE :

for the below added $ mark

$ sed -e 's/.*<name>\([^<]*\)</name>.*/${name}/g' file2.xml

I am getting error./test.sh: line 4: $: command not found

9
  • Which sed are you using? Show output of sed --version. What does sed --help say for using -i?Please quote the relevant part of --help. What other influence does the age of your servers have on seds handling of -i? Commented Jun 15, 2017 at 6:20
  • @Yunnosch i am using an GNU Bash, version 4.2.50. I am unable to get an output for sed --version or sed --help Commented Jun 15, 2017 at 6:25
  • How are you executing the sed scripts you are working on or asking about? Commented Jun 15, 2017 at 6:30
  • I am saving it as myScript.sh file and then execute in bash as ./myScript.sh. hope that makes sense Commented Jun 15, 2017 at 6:37
  • Please type into your bash commandline sed --version. What is the output? Otherwise replace inside your script the existing sed line with sed --version, then execute the script and show the output. Commented Jun 15, 2017 at 6:39

2 Answers 2

1

First, you need "" instead of '' to fetch the value of a variable. And, you should use capture group instead.

$ sed -r -e "s|(.*<name>)[^<]+(</name>)|\1${name}\2|g" -e "s|(.*<age>)[^<]+(</age>)|\1${age}\2|g" File2.txt
<root>
 <name>abcd</name>
 <age>22</age>
</root>

Or just put ${name} outside of the '':

$ sed -r -e 's|(.*<name>)[^<]+(</name>)|\1'${name}'\2|g' -e 's|(.*<age>)[^<]+(</age>)|\1'${age}'\2|g' File2.txt
<root>
 <name>abcd</name>
 <age>22</age>
</root>

PS: maybe can don't have the write permission for File2.txt, so you can NOT use -i.bak

Sign up to request clarification or add additional context in comments.

1 Comment

I think I have the write permissions since I created both files.
0

You may choose to use awk, it's a more straightforward method.

Use the command:

awk 'NR==FNR{
  if(match($0,/name/)){getline;name=$0}
  if(match($0,/age/)){getline;age=$0}
  next}
  /<name>/{gsub(/>.*</,">"name"<",$0)}
  /<age>/{gsub(/>.*</,">"age"<",$0)}
  {print}
' File1.txt File2.xml  

Output:

<root>
 <name>abcd</name>
 <age>22</age>
</root>

Brief explanation:

  1. match(): extract the name & age from File1.txt
  2. gsub(): to substitute name & age in File2.xml

6 Comments

Thanks I will try it. :)
How can I run awk in Bash ? Same as shell scripting. like ./myScript.sh ? would work for awk too?
Hi, no more file would be added in this way. @Hasith, just paste the command to your bash environment should be okay.
I added the code in to a shellscript and executed it to see it print the output as i wanted to see, but it doesn't change the config.xml as I wanted.
@Hasith, awk did not modify the original file actually. But you may follow stackoverflow.com/questions/37795186/… to overwrite the file, a tmp file is required.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.