Merge multiple files found in config file

I have a config file with a bunch of these type of blocks:

        <concat destfile="${standard.js.file}" append="true">
            <filelist dir="${js.dir}/foo" files="foo.js, foo2.js"/>
            <filelist dir="${js.dir}" files="foo3.js"/>
            <filelist dir="${js.dir}/bar/js" files="bar.js" />
            <!-- misc comment to throw things off a bit -->
            <filelist dir="${js.dir}" files="finalfoo.js"/>
        </concat>

I need to grab all these files, in the order they are here, and only within this section (the unique factor is the destfile value), and merge them all into a single file, newfoo.js

I already know how to take multiple files and concatenate them with cat file1 file2 > concatfile, but I'm struggling to figure out how to get the files out of the config file, then combine those.

You mean you want only the data between the concat tags?

--ahamed

I want the content of the files merged into one, so if the contents of ${js.dir}/foo/foo.js is 'foo' and ${js.dir}/foo/foo2.js contains 'bar', the first part of 'newfoo.js' would be:

foo
bar

and would be followed by the contents of all the other JS files within that <concat> element

---------- Post updated at 07:14 PM ---------- Previous update was at 06:42 PM ----------

To clarify:

I want to take that bit of code in the OP, come back with essentially this:

cat $jsdir/foo/foo.js $jsdir/foo/foo2.js $jsdir/foo3.js $jsdir/bar/bar.js $jsdir/finalfoo.js > /finalfoo.js

$jsdir will be defined in the calling script, so it'll look like this:

configfile="config.xml"
jsdir="./js/"

open $configfile
for every filelist between "${standard.js.file}" and "/concat"
files=/dir=\"${js.dir}(.+)\" files=\"(.+)\"/
for each file, prepend $jsdir/
sed $files s/\,// #(remove commas)
cat $files > /finalfoo.js

Try this...

jsdir="./js/"

for file in $( awk -F"[=\"]" '/filelist/{gsub(/\./,"",$3); print $3}' infile )
do
        if [ -f "$file" ]
        then
                cat $file >> newfile.js
        fi
done

--ahamed

1 Like

For testing, I've replaced the check to see if it's a file, and echo'd the file instead, so:

for file in $( awk -F"[=\"]" '/filelist/{gsub(/\./,"",$3); print $3}' infile )
do
    echo "$file"
done

And this is the output I get:

Try this...

#!/bin/bash

jsdir="./js"

file_list=$(awk -F"[=\"]" '
        /standard.js.file/,/<\/concat>/{
        if(/filelist/){dir=$3;l=split($6,arr,", ")
        for(i=1;i<=l;i++){val=val" "dir"/"arr}}}
        END{print val}' infile )

for file in $file_list
do
        eval echo ${file/./}
done

--ahamed

1 Like

Super close -- only problem is it's ouputting two forward slashes before the filename:

./path/to/scripts//foo.js

Edit the jsdir variable, remove the slash at the end...

jsdir="./js"

--ahamed

1 Like

gah, sorry about that. Thanks so much, ahamed!

---------- Post updated at 12:51 AM ---------- Previous update was at 12:18 AM ----------

I'm trying to modify the script for another section (<concat destfile="${standard.css.file}"...) but oddly, even when I change the line on your script from:

/standard.js.file/

to

/standard.css.file/

it's still including the JS block. Is there something else in there that I'm missing?

Escape the . (dots)... Try this... /standard\.css\.file/

--ahamed

1 Like

Already tried that -- same result.

---------- Post updated at 01:33 AM ---------- Previous update was at 01:04 AM ----------

Figured it out -- the values for standard.css.file and standard.js.file we being set above, so it was finding those in the awk, then using all of the stuff below that -- the JS is the first set, so it was including that.

I just added more specificity, /\{standard\.css\.file/

Now it works perfectly. Thanks again!

Back again :-/

The build script was changed so that each file is on its own line, like so:

<concat destfile="${standard.js.file}" append="true">    
    <filelist dir="${js.dir}"
        files="foo.js,
               foo2.js,
               etc.js" />
</concat>

Which this bit does not account for:

    javascript_files=$(awk -F"[=\"]" '
            /\{standard\.js\.file/,/<\/concat>/{
            if(/filelist/){dir=$3;l=split($6,arr,", ")
            for(i=1;i<=l;i++){val=val" "dir"/"arr}}}
            END{print val}' build.xml )

Any thoughts on how to handle the new format?