script to sort files into directories

I was going to put this in GQ but thought this would be better.

I have a folder with a collection of files in it. Over 4000 files to be exact.

The folder resides on a Suse 10.2 Linux box but is accessable over the network to my Windows XP Systems.

All of my computers have read and write access to the folder. Further the folder is mapped to the XP systems as k:

The files all adhere to the same naming standard of


where _ is the space character
AA is two letters
BBBB is four numbers

can be any length.

I assume if I do this on linux there would be a way to send the output of ls to a file, parse the first 5 characters and see if a folder exists with that name. If it does then issue a mv command using the first 5 characters and the wildcard. If the folder does not exist then it would make it then do the moving and then go through the rest of the ls command.

Problem is I don’t know how to do this

I don’t know about linux - from windows you can do it with a .vbs scripting file:

set fso = createObject("Scripting.FileSystemObject"

set rootFold = fso.getFolder ("k:\")

for each efile in rootFold.files

	nprefix = left(, 5)
	if not fso.folderExists ("k:\" & nprefix) then
		fso.createFolder "k:\" & nprefix
	end if

	efile.move "k:\" & nprefix & "\"


set rootfold = nothing

set fso = nothing

(Code has not been tested, might need to specify the entire new pathname in efile.move.)

Hope that this helps out a bit. Moving the files one at a time is much easier than using wildcard moving, because it doesn’t mess up the for each in files loop so badly.

Oh - I forgot a closing parenthesis on the first line

chrisk, thanks I did notice the missing ) I did use the full path in " marks because there were spaces but it failed due to a permissions problem on the share side that I have to fix

Off the top of my head:

#! /bin/bash

find ./ -type f | while read FILE; do


if [ ! -d ${DIR} ]; then
mkdir ${DIR}

mv "${FILE}" ${DIR}


Save it as

chmod 755

mv /base/directory/in/question

cd /base/directory/in/question


Wait, first FIVE characters? Meaning AABBB?

If that’s the case, change:



That is, add a question mark between the second percent and the hyphen.

My perl’s a bit rusty, but this might work too:

use File::Copy;
while (<*>) {
    if(m/([^-]{5})-/) {
        mkdir($1) if ! -d $1;
        move($_, $1);

That {5} bit on line 4 can be changed to + (i.e. m/([^-]+)-/ ) if you don’t need exactly 5 characters before the first hyphen.