Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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.)

share|improve this question
    
For that use case: Maybe it's better not to move the files but to link them? –  Hauke Laging May 6 '13 at 22:10

3 Answers 3

up vote 6 down vote accepted

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 \;
share|improve this answer
    
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 7 '13 at 5:42

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
share|improve this answer
    
That's going to end up with a lot of error messages if the target directory is part of the search tree... Thus if you want to create it there above all then use -prune at least. –  Hauke Laging May 6 '13 at 22:13
    
post edited accordingly, thanks –  sputnick May 6 '13 at 22:17
    
post edited accordingly –  sputnick May 7 '13 at 9:00

Using bash under Linux:

shopt -s nullglob globstar
mv -t ~/epub_directory ~/big_dir/**/*.epub
share|improve this answer
    
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 7 '13 at 5: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 May 7 '13 at 8: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 7 '13 at 10:59

Your Answer

 
discard

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.