I would like to move directories into another location and into subdirectories by first letter.
For example:
./alpha would move to /otherdir/a/
./beta would move to /otherdir/b/
All the subdirectories are created and it's a fixed set, so I don't need to worry about checking or creating those.
I was hoping to use the output from
find . -type d -name "[a-z*]"
, and when I run
find . -type d -name "[a-z*]" | xargs mv -t /dest/
,
all the directories get moved, but of course not into subdirectories. I can't figure out if it's possible to use a second argument for the /dest/first character here/
component, passing the first character of each directory name.
Is there a way to do this, or a different way to a) generate the directory list and b) pass the directory names and first characters to a move command?
2 Answers
There is no reason for using find
(unless the number of directories is huge).
dest_root='/otherdir'
for dir in [a-z]*; do
[ -d "${dir}" ] && mv "${dir}" "${dest_root}/${dir:0:1}"
done
You need to pick up the first letter of the directory. It is easy to do that by running the output of find
through a loop. For example,
for i in $(find . -type d -name "[a-z]*")
do
echo ${i:2:1}
done
This command gives you the first letter of each directory, ignoring the leading ./
. To move it into a destination, you will have to put the directory elsewhere (above the current directory) to avoid recursive moves. Let us say that your destination directories are in ../dest/a
, ../dest/b
, and so on. You can replace the echo
command with mv
and the above loop can become
destination="../dest"
for i in $(find . -type d -name "[a-z]*")
do
mv ${i} ${destination}/${i:2:1}
done
You'll have to adjust for destination.