You are not logged in.
Pages: 1
Hi,
Is it possible the to replace a string with file contents, for example; i have the following XML file:
<?xml version="1.0" encoding="UTF-8"?>
<modification>
<id>Testing</id>
<version>0.0.1</version>
<vqmver required="true">2.5.0</vqmver>
<author><![CDATA[Dragon707]]></author>
<file name="template/a.tpl">
<operation error="log">
<search position="before"><![CDATA[
whooo
]]></search>
<add><![CDATA[
@include[src/script_whooo.js]
]]></add>
</operation>
</file>
<file name="template/b.tpl">
<operation error="log">
<search position="before"><![CDATA[
wheee
]]></search>
<add><![CDATA[
@include[src/script_wheee.js]
]]></add>
</operation>
</file>
</modification>
And the file src/script_whooo.js contains:
alert(1);
And the file src/script_wheee.js contains:
alert(2);
What i want is that the string "@include[src/script_whooo.js]" replaces the content with src/script_whooo.js. The expected output is then:
<?xml version="1.0" encoding="UTF-8"?>
<modification>
<id>Testing</id>
<version>0.0.1</version>
<vqmver required="true">2.5.0</vqmver>
<author><![CDATA[Dragon707]]></author>
<file name="template/a.tpl">
<operation error="log">
<search position="before"><![CDATA[
whooo
]]></search>
<add><![CDATA[
alert(1);
]]></add>
</operation>
</file>
<file name="template/b.tpl">
<operation error="log">
<search position="before"><![CDATA[
wheee
]]></search>
<add><![CDATA[
alert(2);
]]></add>
</operation>
</file>
</modification>
Last edited by Dragon707 (2014-11-14 12:06:22)
Offline
Yes, the read command "r" will read in a named file into the pattern space after the addressed line (which you then delete to replace):
/address/r filename
/address/d
You'll need to escape the special characters in your address.
"...one cannot be angry when one looks at a penguin." - John Ruskin
"Life in general is a bit shit, and so too is the internet. And that's all there is." - scepticisle
Offline
I don't think you can get the filename from the file into the 'r' command of sed without naming the filenames explicitly.
Try this in bash:
while read; do
[[ "$REPLY" =~ ^(.*)@include\[([^\]]*)\](.*)$ ]] &&
REPLY=${BASH_REMATCH[1]}$(cat "${BASH_REMATCH[2]}")${BASH_REMATCH[3]}
echo "$REPLY"
done < script.xml
It only does one @include[] per line though.
Offline
You can name them explicitly, and use the pattern to select which to use.
Pretty sure you can also, if you wrap your sed script in a shell script, pass in the relevant names:
sed '/pattern1/r '"$1"'
/pattern1/d
/pattern2/r '"$2"'
/pattern2/r' inputfile
Can't find a script where I do that at the moment though (except in awk).
EDIT: found one where I do that in the pattern space, so yeah, it should work.
Last edited by skanky (2014-11-11 17:23:24)
"...one cannot be angry when one looks at a penguin." - John Ruskin
"Life in general is a bit shit, and so too is the internet. And that's all there is." - scepticisle
Offline
I don't think you can get the filename from the file into the 'r' command of sed without naming the filenames explicitly.
Try this in bash:while read; do [[ "$REPLY" =~ ^(.*)@include\[([^\]]*)\](.*)$ ]] && REPLY=${BASH_REMATCH[1]}$(cat "${BASH_REMATCH[2]}")${BASH_REMATCH[3]} echo "$REPLY" done < script.xml
It only does one @include[] per line though.
Thanks for your answer, i got it to work however, i still miss the tabs in the output.xml file. Is there a way to keep the tabs in the output.xml?
#!/bin/bash
INPUT="input.xml"
OUTPUT="output.xml"
echo "" > $OUTPUT
while read; do
[[ "$REPLY" =~ ^(.*)@include\[([^\]]*)\](.*)$ ]] &&
REPLY=${BASH_REMATCH[1]}$(cat "${BASH_REMATCH[2]}")${BASH_REMATCH[3]}
echo $REPLY >> $OUTPUT
done < $INPUT
Offline
Keep the quotes with the command echo "$REPLY".
If an included file has multiple lines, you can give all lines indentation with sed:
INPUT=input.xml
OUTPUT=output.xml
while read; do
[[ "$REPLY" =~ ^(.*)@include\[([^\]]*)\](.*) ]] &&
REPLY=$(sed "s/^/${BASH_REMATCH[1]}/" "${BASH_REMATCH[2]}")${BASH_REMATCH[3]}
echo "$REPLY"
done < $INPUT > $OUTPUT
Offline
Keep the quotes with the command echo "$REPLY".
If an included file has multiple lines, you can give all lines indentation with sed:INPUT=input.xml OUTPUT=output.xml while read; do [[ "$REPLY" =~ ^(.*)@include\[([^\]]*)\](.*) ]] && REPLY=$(sed "s/^/${BASH_REMATCH[1]}/" "${BASH_REMATCH[2]}")${BASH_REMATCH[3]} echo "$REPLY" done < $INPUT > $OUTPUT
Thanks! That did the trick
Offline
If I am processing an xml file in a shell script then I tend to use xmlstarlet. Makes things simpler and is ultimately more robust. It's in the standard community packages.
Offline
Pages: 1