Ask Different is a question and answer site for power users of Apple hardware and software. Join them; it only takes a minute:

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've a lot of files (1000+) in a single directory, and i would like to organize them into sub directories, according to their first letter. So i've 200 files starting with A, and i would like to move them into subdirectory "A", then all "B" files etc. etc.

How to do ?

share|improve this question
up vote 4 down vote accepted

In a terminal: cd into the directory in question, then

for x in `ls -1 | sed -e 's/^\(.\).*/\1/' | sort -u`; do
mkdir $x && mv -i ${x}?* $x

This assumes that no files have a single character name before you start. If they do, you might move them aside before you run the above procedure:

mkdir singles && mv ? singles

and then move them to their appropriate destinations aftwards.

Edit: See the comments below for some caveats. If you run into problems with too long command lines, you could replace the second line by

mkdir $x && find . -maxdepth 1 -name "${x}?*" -exec mv -i {} $x \;
share|improve this answer
This fails with files that have spaces (or newlines) in their name. Command substitution might also result in too many arguments. – slhck May 28 '12 at 21:50
@slhck: No, spaces in filenames are no problem, unless the filename begins with a space. Yes, newlines would be a problem, but both of these cases are distinctly unusual. Command substitution could be a problem if too many filenames start with the same letter. But I think the current limit on command line length is quite generous, so this is not very likely with the number of files indicated. Still, I'll add a fix for that to the answer. – Harald Hanche-Olsen May 29 '12 at 20:12
Ah, I see now, my bad, +1 to you! – slhck May 29 '12 at 20:13

Here's a Ruby one-liner:

ruby -e 'require "FileUtils"; Dir["*"].each { |f| next if; d = f[0]; Dir.mkdir d rescue nil;,d) }'

It basically iterates over all files, creates the directories if possible and moves the files to it afterwards.

Just execute this line from the directory.

share|improve this answer

This would also work if the filenames start with multibyte characters (like Ä or あ):

ls | iconv -f utf8-mac -t utf-8 | LC_CTYPE=UTF-8 cut -c1 | uniq | while IFS= read -r l; do
  mkdir -- "$l"
  mv -- "${f[@]}" "$l"

iconv -f utf8-mac -t utf-8 converts text from a partially decomposed form used by HFS+ to precomposed form. See Text Encodings in VFS or this question. LC_CTYPE=UTF-8 makes cut -c1 consider multibyte characters as single characters.

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.