I have script se.sh
:
#!/bin/bash
files="$1"
shopt -s nullglob
shopt -s extglob
for f in a/path/to/all/files/${files}; do
echo "file process:${f}"
done
shopt -u nullglob
shopt -u extglob
When I run:./se.sh "a*.txt"
, it will process the correct files in the folder.
When I run ./se.sh "{a,1}*.txt"
, I want process files started with a*.txt
or 1*.txt
, but it didn’t run as I expected.
I have searched for quite a while, see
using-a-glob-expression-passed-as-a-bash-script-argument,
how-to-pass-a-globbing-pattern-as-parameter-to-a-function-in-bash
Not an answer. Quick demo of my comment:
$ ls
config.json example.tcl tests.toml
$ files="{e,t}*"
$ echo "$files"
{e,t}*
$ declare -a x=( "$files" )
$ declare -p x
declare -a x=([0]="{e,t}*")
$ eval declare -a x=( "$files" )
$ declare -p x
declare -a x=([0]="example.tcl" [1]="tests.toml")
Of course, you don’t want to blindly eval
any user input without thorough validation.
{a,1}
is not an extglob, it is braces expansion. If you want extglob@(a|1)*.txt
use extglob.To expand on KamilCuk’s answer, look at the order of shell expansions — brace expansion happens before parameter expansion. You’ll need
eval
if you want to expand braces stored in a variable.You can also use the standard glob
[a1]*.txt
instead of that particular brace expansion.