5

I have a directory that contains many subdirectories. The subdirectories contain lots of types of files with different file extensions. I want to move (not copy) all the files of one type into a new directory. I need all these files to be in the same directory, i.e. it needs to be flat.

(My use case is that I want to move ebooks called *.epub from many directories into a single folder that an EPUB reader can find.)

johntait.org
  • 1,362

3 Answers3

12

In zsh, you can use a recursive glob:

mkdir ~/epubs
mv -- **/*.epub ~/epubs/

In bash ≥4, run shopt -s globstar (you can put this in your ~/.bashrc) then the command above. In ksh, run set -o globstar first.

With only POSIX tools, run find:

find . -name '*.epub' -exec mv {} ~/epubs \;
  • Note that bash (and fish) contrary to zsh or ksh93 do follow symlinks when descending the directory tree (see here for details). find will include dot files and follow dotdirs, not **. With **, you may run into the too many args limit which zsh and ksh93 have work around for, but not bash. – Stéphane Chazelas May 07 '13 at 05:42
6

Try doing this :

mkdir ../new_dir
find . -type f -name '*.epub' -exec mv {} ../new_dir/ \;

if all the files are named name.epub, then you need to increment a variable like this (using )

mkdir ../new_dir
find . -type f -name '*.epub' |
    while read a; do
        ((c++))
        base="${a##*/}"
        mv "$a" "../new_dir/${base%.epub}_$(printf %.03d $c).epub"
    done
3

Using bash under Linux:

shopt -s nullglob globstar
mv -t ~/epub_directory ~/big_dir/**/*.epub
glenn jackman
  • 85,964
  • Note that there's nothing Linux-specific in there. mv -t is GNU specific though (and most Linux distributions have GNU mv as their mv). There's no reason to be using mv -t here though. – Stéphane Chazelas May 07 '13 at 05:54
  • @StephaneChazelas I added that. In practice, for most people, GNU <-> Linux || Cygwin (as opposed to OSX, *BSD, Solaris). I didn't see the point of using mv -t either but didn't feel comfortable changing that (it's a matter of style rather than correctness). – Gilles 'SO- stop being evil' May 07 '13 at 08:07
  • I originally had something a bit more complicated piping in to xargs mv -t dir. I left that form of mv here – glenn jackman May 07 '13 at 10:59