While the general problem of identifying extensions is hard, you can clean up the script a bit:
- Tell
findto only consider files with an extension:-iname '*.*' - Use
awkinstead ofcutting yourself: - Use a script, and then tell
findto exec that script.
Thus: a script called, say, move.sh:
#! /bin/bash
for i
do
ext=/some/where/else/$(awk -F. '{print $NF}' <<<"$i")
mkdir -p "$ext"
mv "$i" "$ext"
done
Then run find thus:
find . -name '*.*' -type f -exec move.sh {} +
This has the problem that you can't rearrange within the folder, so you could use xargs:
find . -name '*.*' -type f -print0 > /tmp/temp
xargs -0 move.sh < /tmp/tmp
I'm not too sure of the efficiency involved, but another approach would be to get all the extensions, then move all the files involved in one swoop.
Something like:
find . -name '*.*' -type f -print0 | sed -z 's/.*\.//g' | sort -zu > /tmp/file-exts
This should get you a list of unique file extensions. Then our move.sh will look like:
#!/bin/bash
for i
do
mkdir -p "$i"
find . -name "*.$i" -type f -exec mv -t "$i" {} +
done
And we'll run it:
xargs -0 move.sh < /tmp/file-exts
I make quite a few assumptions in this post, such as sed and sort supporting -z (allowing them to work with the NUL-terminated lines that find and xargs thrive on).