Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ls with numeric range doesn't work inside bash script

Tags:

bash

ls

I have a folder with files named as file_1.ext...file_90.ext. I can list a range of them with the following command:

$ ls /home/rasoul/myfolder/file_{6..19}.ext

but when I want to use this command inside a bash script, it doesn't work. Here is a minimal example:

#!/bin/bash

DIR=$1
st=$2
ed=$3

FILES=`ls ${DIR}/file\_\{$st..$ed\}.ext`
for f in $FILES; do
  echo $f
done

running it as,

$ bash test_script.sh /home/rasoul/myfolder 6 19

outputs the following error message:

ls: cannot access /home/rasoul/myfolder/file_{6..19}.ext: No such file or directory
like image 985
Rasoul Avatar asked May 16 '26 18:05

Rasoul


2 Answers

Brace expansion happens before variable expansion.

(Moreover, don't parse ls output.). You could instead say:

for f in $(seq $st $ed); do 
    echo "${DIR}/file_${f}.ext";
done
like image 66
devnull Avatar answered May 18 '26 10:05

devnull


BASH always does brace expansion before variable expansion which is why ls is looking for a file /home/rasoul/myfolder/file_{6..19}.ext.

I personally use seq when I need to expand a number range that has variables in it. You could also use eval with echo to accomplish the same thing:

eval echo {$st..$ed}

But even if you used seq in your script, ls would not iterate over your range without a loop. If you want to check if files in the range exist, I would also avoid using ls here as you will get errors for every file in the range that doesn't exist. BASH can check if a file exists using -e.

Here is a loop that would check if a file exists within the range between variables $st and $ed and print it if it does:

for n in $(seq $st $ed); do 
    f="${DIR}/file_$n.ext"
    if [ -e $f ]; then
        echo $f
    fi
done
like image 35
John B Avatar answered May 18 '26 10:05

John B



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!