| Author |
Inserting Text into a file
|
|
| ianbacon999@hotmail.com 2006-07-19, 7:56 am |
| Hi, I need help inserting text into a file.
Here's what I have so far
#!/bin/bash
if [ $# -ne 1 ]; then
echo "Usage:$0 insert "
exit
fi
JMS_INSERTFILE=$1
cat jms.bak | nawk -v filename=$JMS_INSERTFILE '
BEGIN{if (filename=="")
{
print "Error:no filename given";
exit 1;
}
}
!/\<\/queue\>/ {print}
/\/\>/ {while( getline<filename) print;}
' > jms.xml
but this inserts after the first "/>" where as I need it to insert
after the last "/>". Or I need to insert before the last "</"
If anyone could help with this is would be greatly appreciated.
Cheers
| |
| Ed Morton 2006-07-19, 7:56 am |
| ianbacon999@hotmail.com wrote:
> Hi, I need help inserting text into a file.
<snip>
> cat jms.bak | nawk -v filename=$JMS_INSERTFILE '
> BEGIN{if (filename=="")
> {
> print "Error:no filename given";
> exit 1;
> }
> }
> !/\<\/queue\>/ {print}
> /\/\>/ {while( getline<filename) print;}
> ' > jms.xml
>
> but this inserts after the first "/>" where as I need it to insert
> after the last "/>". Or I need to insert before the last "</"
>
> If anyone could help with this is would be greatly appreciated.
You need to read the file twice. First to determine which is the last
occurrence of the pattern and second to insert the text, e.g.
awk -v filename="$JMS_INSERTFILE" '
NR==FNR && /\/\>/ { lineNr=NR; next }
!/\<\/queue\>/ {print}
FNR==lineNR { while( getline<filename) print;}
' jms.bak jms.bak
Be careful when using getline as it has many caveats. For example, the
above will change the value of $0 so if you wanted to insert the
contents of "filename" BEFORE the line with the matching pattern in the
original file, then you'd have a problem because the $0 after the
getline loop would be the last record from "filename", not the current
record from "jms.bak".
If you don't want to manually specify the input file name twice on the
command line, add this to the BEGIN section instead:
ARGV[ARGC++]=ARGV[1]
Regards,
Ed.
| |
| Xicheng Jia 2006-07-19, 7:56 am |
| ianbacon999@hotmail.com wrote:
> Hi, I need help inserting text into a file.
>
> Here's what I have so far
>
> #!/bin/bash
> if [ $# -ne 1 ]; then
> echo "Usage:$0 insert "
> exit
> fi
>
> JMS_INSERTFILE=$1
>
> cat jms.bak | nawk -v filename=$JMS_INSERTFILE '
> BEGIN{if (filename=="")
> {
> print "Error:no filename given";
> exit 1;
> }
> }
> !/\<\/queue\>/ {print}
> /\/\>/ {while( getline<filename) print;}
> ' > jms.xml
>
> but this inserts after the first "/>" where as I need it to insert
> after the last "/>". Or I need to insert before the last "</"
>
> If anyone could help with this is would be greatly appreciated.
>
> Cheers
Maybe you can try:
awk -F'\>' -v OFS='\>' -v ins="`cat $JMS_INSERTFILE`" '
NF > 1 { $NF = ins $NF }1' jms.xml
Xicheng
| |
| Ed Morton 2006-07-19, 6:57 pm |
| Ed Morton wrote:
<snip>
Ooops.
> awk -v filename="$JMS_INSERTFILE" '
> NR==FNR && /\/\>/ { lineNr=NR; next }
Change the above to:
NR==FNR { if ($0 ~ /\/\>/) lineNr=NR; next }
to make sure you always do a "next" for every line of the file on the
first pass, not just the line that matches the pattern.
> !/\<\/queue\>/ {print}
> FNR==lineNR { while( getline<filename) print;}
> ' jms.bak jms.bak
Regards,
Ed.
| |
| ianbacon999@hotmail.com 2006-07-19, 6:57 pm |
| Thanks for this it works great. One further question - how do i insert
before the last </?
Ed Morton wrote:
> Ed Morton wrote:
> <snip>
>
> Ooops.
>
>
> Change the above to:
>
> NR==FNR { if ($0 ~ /\/\>/) lineNr=NR; next }
>
> to make sure you always do a "next" for every line of the file on the
> first pass, not just the line that matches the pattern.
>
>
> Regards,
>
> Ed.
| |
| ianbacon999@hotmail.com 2006-07-19, 6:57 pm |
| When all was going sooo well. I've embedded this into a script and
when run within this script the file get corrupt. It works on its own
though
Ed Morton wrote:
> Ed Morton wrote:
> <snip>
>
> Ooops.
>
>
> Change the above to:
>
> NR==FNR { if ($0 ~ /\/\>/) lineNr=NR; next }
>
> to make sure you always do a "next" for every line of the file on the
> first pass, not just the line that matches the pattern.
>
>
> Regards,
>
> Ed.
| |
| Harlan Grove 2006-07-19, 6:57 pm |
| Ed Morton wrote...
....
>Ooops.
....
>Change the above to:
>
>NR==FNR { if ($0 ~ /\/\>/) lineNr=NR; next }
....[color=darkred]
....
There's another bug, lineNR rather than lineNr. Case sensitivity can be
a PITA.
Wouldn't using tac | awk '..insert before first instance..' | tac be
cleaner?
| |
| dfeustel@mindspring.com 2006-07-19, 6:57 pm |
| Why not use ex to read in the entire file.
Then search backwards from the EOF til you find the
first '>'.
Then insert the text after that character?
That could all be done as a very simple batch script.
| |
| Xicheng Jia 2006-07-19, 6:57 pm |
| dfeustel@mindspring.com wrote:
> Why not use ex to read in the entire file.
> Then search backwards from the EOF til you find the
> first '>'.
> Then insert the text after that character?
> That could all be done as a very simple batch script.
The OP can also use any tools which support Perl-compatible regex's
lookahead construct(?!...), like:
v=`cat insert_file` perl -0777pe 's~/>(?!.*/> )~/>$ENV{v}~s' file.xml
v=`cat insert_file` ruby -0777pe 'sub(%r{/>(?!.*/> )}m,"/>"+ENV["v"])'
file.xml
which insert the whole contents of a file right after the last instance
of '/>' in file.xml
Xicheng
| |
| Ed Morton 2006-07-19, 9:56 pm |
| ianbacon999@hotmail.com wrote:
> Thanks for this it works great. One further question - how do i insert
> before the last </?
Just change the pattern from /\/\>/ to /<\//. And please don't top-post.
Ed.
>
> Ed Morton wrote:
>
>
>
| |
| Ed Morton 2006-07-19, 9:56 pm |
| ianbacon999@hotmail.com wrote:
> When all was going sooo well. I've embedded this into a script and
> when run within this script the file get corrupt. It works on its own
> though
>
Then there's something wrong with your script that calls it. Maybe
you're trying to write back to the same file you're reading from while
you're reading it?
Ed.
> Ed Morton wrote:
>
>
>
| |
| Ed Morton 2006-07-19, 9:56 pm |
| Harlan Grove wrote:
> Ed Morton wrote...
> ...
>
>
> ...
>
>
> ...
>
>
> ...
>
> There's another bug, lineNR rather than lineNr.
Thanks.
Case sensitivity can be
> a PITA.
>
> Wouldn't using tac | awk '..insert before first instance..' | tac be
> cleaner?
>
tac isn't always available and if you're going to use awk anyway....
Ed.
| |
| ianbacon999@hotmail.com 2006-07-20, 7:56 am |
|
Ed Morton wrote:
> Harlan Grove wrote:
>
>
> Thanks.
>
> Case sensitivity can be
>
> tac isn't always available and if you're going to use awk anyway....
>
> Ed.
Thanks for all you help with this, I am now getting the results I want.
Cheers
|
|
|
|