Take the 2-minute tour ×
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.

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
done

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

share|improve this question
add comment

2 Answers

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
add comment

In zsh:

DB_VERSION=02
glob="<$((DB_VERSION+1))->"
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
add comment

Your Answer

 
discard

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.