I have a directory like this

mkdir test
cd test
touch file{0,1}.txt otherfile{0,1}.txt stuff{0,1}.txt

I want to run some command such as ls on certain types of files in the directory and have the * (glob) expand to all possibilities for the filename.

echo 'file otherfile' | tr ' ' '\n' | xargs -I % ls %*.txt

This command does not expand the glob and tries to look for the literal 'file*.txt'

How do I write a similar command that expands the globs? (I want to use xargs so the command can be run in parallel)


Solution 1:

This is old, but i ran into this issue and found another way to fix it. Have xargs execute bash with -c and your command. For example:

echo 'file otherfile' | tr ' ' '\n' | xargs -I % bash -c "ls %*.txt"

This forces glob expansion.

Solution 2:

I was able to get the functionality I wanted by using the -1 flag for ls. Here is how my command looks:

ls -1 {file,otherfile}*.txt | xargs -I% echo mycommand %

Solution 3:

What you are doing won't work because the glob is not expanded by the xargs command when it runs, it is expanded by the shell as soon as you hit enter and before any of those commands starts running. So the glob it tries to expand is:

%*.txt

and as there are no files matching that pattern it leaves it alone and then when xargs runs it substitutes it's arguments into that string.

The simplest solution is probably just to write a pattern which matches all the files you are interested in in one go:

ls {file,otherfile}*.txt