Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm trying to create a shell script that runs through a bunch of SQL scripts.

I've these files:

$ ls upgrade/
01-foo.sql 02-bar.sql 02-baz.sql 03-foo1.sql 04-buz.sql

And I've got the version of the current db, e.g. DB_VERSION=02

How can I now easily loop through and glob the files with a prefix greater than my $DB_VERSION, and run them in order ?

i.e. I'd like to do

for f in ???? ; do 
   mysql < $f

and, with DB_VERSION=02, run the 03-foo1.sql and 04-buz.sql , in that order.

share|improve this question
up vote 3 down vote accepted

Initial setup: touch 01-foo.sql 02-bar.sql 02-baz.sql 03-foo1.sql 04-buz.sql 09-quux.sql 10-lala.sql 99-omg.sql

Actual code: curr=02; for file in ??-*.sql; do ver="${file:0:2}"; [ "$ver" -gt "$curr" ] && echo "$file"; done

I.e., define the current version to be 02 and then look at all files (the globbing is alphabetical), executing them if their number prefix is numerically greater. Substitute mysql (or what have you) for echo.

share|improve this answer
have to be careful with invalid octal values: [[ "08" -gt "07" ]] && echo y produces [[: 08: value too great for base (error token is "08") -- you probably want to stick with string comparison. – glenn jackman Oct 11 '11 at 15:34
glenn jackman: hmm, that's only if you use [[ instead of [. Both are built-in, so I do not immediately see the benefit of using [[ here. Am I missing something? – janmoesen Oct 11 '11 at 19:32
I didn't realize they act differently in this regard. The main benefit of [[ is additional operators: == and != do glob-style pattern matching and =~ does regex matching. No word splitting is performed in [[, so there are fewer surprises if you forget to quote variables. documentation: gnu.org/software/bash/manual/… – glenn jackman Oct 11 '11 at 19:53
If you do want to use [[, you can tell bash to treat the numbers as decimal regardless of the leading 0: [[ "10#$ver" -gt "10#$curr" ]] – glenn jackman Oct 11 '11 at 19:56
glenn jackman: thanks, I knew about those extra features of [[ (that's why I wondered why it was preferable here), apart from the base specifier. Neat! – janmoesen Oct 12 '11 at 6:59

In zsh:

for x in $~glob-*; do mysql <$x; done

The <LOW-UP> glob operator matches integers in a range. You can only use a literal integer, not the result of a computation. Hence, we first build a glob pattern as the value of a parameter, then use this parameter as a glob pattern thanks to the ~ parameter expansion option.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.