0

I have a linux webserver with about 25.000 images in one directory. They are all lowercase and in the format two letters, three digits and jpg as the extension. Because that many files in one folder is getting difficult to manage I want to move them to subfolders based on the first two letters of the filename like this:

/images/ab123.jpg --> /images/ab/ab123.jpg
/images/ab383.jpg --> /images/ab/ab383.jpg
/images/sk234.jpg --> /images/sk/sk234.jpg

I already managed to list all about 250 different letter combinations and create subdirectories:

ls | awk '{print substr($0,0,2)}' | uniq | xargs mkdir

But I can't manage to move the files. Any ideas?

user168080
  • 41
  • 2

4 Answers4

1

Bash can do the substring extraction for you.

Here's a one-liner that presumes that the destination directories already exist:

cd /images; for f in *.jpg; do mv "$f" "${f:0:2}"; done

This small script makes the directories for you and does the moves.

cd /images &&
for f in *.jpg
do
    pre=${f:0:2}
    if [[ ! -d $pre ]]
    then
        mkdir "$pre"
    fi
    mv "$f" "$pre"
done
Dennis Williamson
  • 62,149
  • 16
  • 116
  • 151
0

Try it with

for i in $(find . -type f -maxdepth 1); do mv $i $(echo $i|awk '{print substr($0,0,2)}');done
etagenklo
  • 5,834
  • 1
  • 27
  • 32
  • Didn't work that way. But with a little modification it worked like this: for i in *.jpg; do mv $i $(echo $i|awk '{print substr($0,0,2)}'); done Thanks! – user168080 Apr 06 '13 at 14:06
0

Many files, so let's avoid globbing, in favor of find(1): And I use Zsh as shell: A problem remains with filenames containing double quotes

find  -maxdepth 1  -type f -exec zsh -c 'a="{}";b=${a:0:4}; mkdir -p $b; mv -t $b $a'   \;
mmaruska
  • 101
-1

I believe that simplest way is to use rename command with appropriate regex:

rename 's/^([a-zA-Z]{2})/$1\/$&/' *.jpg

Description:

$& - its original filename,

$1 - matched 2 first letters, used here as directory name
Dennis Williamson
  • 62,149
  • 16
  • 116
  • 151
Tomasz Olszewski
  • 898
  • 1
  • 9
  • 20
  • I tried this as I was curious to see if rename took sed-like syntax in expressions. This did not work. – Matthew Ife Apr 06 '13 at 19:24
  • 1
    @MIfe: There are two different versions of `rename`. One takes glob style arguments and the other takes regular expressions (`sed` like). Sometimes the latter is called `prename`. It's really just a simple Perl script. [One source](http://cpansearch.perl.org/src/RMBARKER/File-Rename-0.06/rename.PL). – Dennis Williamson Apr 06 '13 at 21:19