0

I have the following simple script to loop through files with specific extensions and generate an XML file with the parsed file names without extensions. However, if any of the extensions does not exist in the directory, it results in *.ext and messes up the results. How do I ensure that it only grabs names of the real files and not something like *.wlens?

P.S. I'm doing the more complex name parsing (sed) because files might contain "." in the name. If there are more efficient ways of doing that, I would appreciate your input.

#!/bin/bash

echo "
<?xml version="1.0" encoding="UTF-8"?>

<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
    " > retrieve_xmd_build_package.xml

for i in *.{wdash,wcomp,wlens};
do
   
    echo "<members>" >> retrieve_xmd_build_package.xml 
    echo "    " "$i"| sed 's#^\(.*\)\.\(.*\)#\1#'     >> retrieve_xmd_build_package.xml 
    echo "</members>" >> retrieve_xmd_build_package.xml 
done

echo "<name>WaveXMD</name>" >> retrieve_xmd_build_package.xml 
echo "

   </types>

   <version>56.0</version>

</Package>

" >> retrieve_xmd_build_package.xml


Here is the result with an incorrect entry for one of the extensions:


<?xml version=1.0 encoding=UTF-8?>

<Package xmlns=http://soap.sforce.com/2006/04/metadata>
    <types>
    
<members>
     weekday DASH
</members>
<members>
     *
</members>
<members>
     weekday LENS 2
</members>
<members>
     weekday LENS
</members>
<name>WaveXMD</name>


   </types>

   <version>56.0</version>

</Package>

1 Answer 1

1

Personally, I'd be inclined to use find, but you could do this in bash by setting the nullglob option. i.e. somewhere before your for loop, add:

shopt -s nullglob

From man bash:

nullglob

If set, bash allows patterns which match no files (see Pathname Expansion above) to expand to a null string, rather than themselves.

For example, compare the difference with nullglob set and unset. First, unset (which is normally the default unless you set it in .bashrc or other profile script):

$ shopt -u nullglob
$ for i in *.{wdash,wcomp,wlens}; do echo "$i"; done
*.wdash
*.wcomp
*.wlens

None of those file globs exist in the current directory, so with nullglob unset, bash expands the unmatched globs to themselves (i.e. just uses the globs as literal strings)

Next with nullglob set:

$ shopt -s nullglob
$ for i in *.{wdash,wcomp,wlens}; do echo "$i"; done

i.e. the for loop doesn't print anything because the nullglob setting prevents an unmatched glob from expanding to itself.

Beware that in bash, the failglob option takes precedence over nullglob. So if failglob is set, nullglob has no effect. If failglob might be set, you'd need to unset it with shopt -u failglob in order to be able to use nullglob.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .