1

I can run the following command on the Linux command line and it correctly lists all the files that have the ABC- and XYZ- prefixes:

    ls {ABC-,XYZ-}*.xml

    Result: ABC-01.xml  ABC-02.xml  ABC-03.xml  XYZ-01.xml  XYZ-02.xml

Now, I figured that I could use a variable as follows:

    file_pfx={ABC-,XYZ-}

and then use the variable in the "ls" command combined with "eval":

    eval 'ls ${file_pfx}*.xml'

    Result: ls: {ABC-,XYZ-}*.xml: No such file or directory

What am I doing wrong?

Thanks

user3152289
  • 107
  • 8
  • You can't store the braced expressioni in a variable because brace expansion takes place *before* parameter substitution. See the [order of expansions in the manual](https://www.gnu.org/software/bash/manual/bashref.html#Shell-Expansions). – glenn jackman Aug 19 '17 at 20:42
  • Before actually using `eval`, see ["Why should eval be avoided in Bash, and what should I use instead?"](https://stackoverflow.com/questions/17529220/why-should-eval-be-avoided-in-bash-and-what-should-i-use-instead) – John1024 Aug 19 '17 at 20:57
  • Thanks for including a complete test case with output! +1 – that other guy Aug 19 '17 at 21:31

3 Answers3

4

Don't use eval. You can use extended globbing instead:

#! /bin/bash
shopt -s extglob
prefix='ABC-|XYZ-'
ls @($prefix)*.xml
choroba
  • 231,213
  • 25
  • 204
  • 289
3

I would advise you to use an array

$ touch ABC-01.xml  ABC-02.xml  ABC-03.xml  XYZ-01.xml  XYZ-02.xml

$ files=( {ABC-,XYZ-}*.xml )

$ printf "%s\n" "${files[@]}"
ABC-01.xml
ABC-02.xml
ABC-03.xml
XYZ-01.xml
XYZ-02.xml
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
1

You should use double quotes to allow variable expansion ($file_pfx):

eval "ls ${file_pfx}*.xml"

Notice I'm assuming your filenames don't contain spaces.

Anyway, be careful with the use of eval.

whoan
  • 8,143
  • 4
  • 39
  • 48