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

Hasith
  • 73
  • 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`? – Yunnosch Jun 15 '17 at 06: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` – Hasith Jun 15 '17 at 06:25
  • How are you executing the sed scripts you are working on or asking about? – Yunnosch Jun 15 '17 at 06:30
  • I am saving it as myScript.sh file and then execute in bash as ./myScript.sh. hope that makes sense – Hasith Jun 15 '17 at 06: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. – Yunnosch Jun 15 '17 at 06:39
  • @Yunnosch I tried both that. No Luck :( this is a line in another script file which I did not write `appGroup=$(cat $ConfigFile | grep appGroup | grep -v 'appGroups'| grep -v '<!'| sed -e 's,.*\([^<]*\).*,\1,g') ` this works fine – Hasith Jun 15 '17 at 06:42
  • Give more details on "No Luck". What happened or in which way did it fail? Did anything happen, even if not what we want? – Yunnosch Jun 15 '17 at 06:47
  • for both methods, `sed: Not a recognized flag: - Usage: sed [-n] [-u] Script [File ...] sed [-n] [-u] [-e Script] ... [-f Script_file] ... [File ...]` – Hasith Jun 15 '17 at 06:49
  • Are we talking AIX? In that case check https://stackoverflow.com/questions/7232797/sed-on-aix-does-not-recognize-i-flag – Yunnosch Jun 15 '17 at 06:55

2 Answers2

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

Weike
  • 1,232
  • 12
  • 15
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
CWLiu
  • 3,913
  • 1
  • 10
  • 14
  • Thanks I will try it. :) – Hasith Jun 15 '17 at 06:45
  • How can I run awk in Bash ? Same as shell scripting. like ./myScript.sh ? would work for awk too? – Hasith Jun 15 '17 at 06:53
  • Hi, no more file would be added in this way. @Hasith, just paste the command to your bash environment should be okay. – CWLiu Jun 15 '17 at 06:58
  • 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 Jun 29 '17 at 06:09
  • @Hasith, `awk` did not modify the original file actually. But you may follow https://stackoverflow.com/questions/37795186/overwrite-input-file-using-awk to overwrite the file, a tmp file is required. – CWLiu Jun 29 '17 at 06:21
  • Thanks, I checked that, I am afraid that it might not work for me since, I need to edit only specific tags in the xml file. If I used a temp file I would have to create the whole config file in the script. And I can't change two different xml files which have the same tags that I want to change and have more tags unique to that file. – Hasith Jun 29 '17 at 07:16