38

I have a directory with image files foo_0.jpg to foo_99.jpg. I would like to copy files foo_0.jpg through foo_54.jpg.

Is this possible just using bash wildcards?

I am thinking something like cp foo_[0-54].jpg but I know this selects 0-5 and 4 (right?)

Also, if it is not possible (or efficient) with just wildcards what would be a better way to do this?

Thank you.

DQdlM
  • 9,814
  • 13
  • 37
  • 34

5 Answers5

66

I assume you want to copy these files to another directory:

cp -t target_directory foo_{0..54}.jpg
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • 1
    +1: Like the use of the {0..54}. That's much cleaner than the globbing – David W. Jun 22 '11 at 17:18
  • You are amazing! Would you happen to know where in the bash manual that is described? I can't find it but I now remember seeing it somewhere. Nevermind. Found it under Brace Expansion. – grok12 Jun 22 '11 at 17:21
  • 1
    Apparently this brace expansion sequence expression is used for file name matching but not for regex. – grok12 Jun 22 '11 at 18:34
10

I like glenn jackman answer, but if you really want to use globbing, following might also work for you:

$ shopt -s extglob
$ cp foo_+([0-9]).jpg $targetDir

In extended globbing +() matches one or more instances of whatever expression is in the parentheses.

Now, this will copy ALL files that are named foo_ followed by any number, followed by .jpg. This will include foo_55.jpg, foo_139.jpg, and foo_1223218213123981237987.jpg.

On second thought, glenn jackman has the better answer. But, it did give me a chance to talk about extended globbing.

Community
  • 1
  • 1
David W.
  • 105,218
  • 39
  • 216
  • 337
4

ls foo_[0-9].jpg foo_[1-4][0-9].jpg foo_5[0-4].jpg

Try it with ls and if that looks good to you then do the copy.

grok12
  • 3,526
  • 6
  • 26
  • 27
  • 1
    @DigitalRoss: That's good except it will match files like foo_a.jpg if they exist. Perhaps replacing your ?'s with [0-9]'s is the best solution. – grok12 Jun 22 '11 at 16:54
4
for i in `seq 0 54`; do cp foo_$i.jpg <target>; done
pajton
  • 15,828
  • 8
  • 54
  • 65
0

An extension answer of @grok12's answer above

$ ls foo_([0-9]|[0-4][0-9]|5[0-4]).jpg

Basically the regex above will match below

  • anything with a single digit OR
  • two digits and that first digit must be between 0-4 and second digit between 0-9 OR
  • two digits and that first digit is 5 and second digit between 0-9

Alternatively you can achieve similar result with regex below

$ ls file{[0-9],[0-4][0-9],5[0-4]}.txt
Isaac
  • 12,042
  • 16
  • 52
  • 116