5

Given the following structure:

source/
  dir1/
   file1.ext1
   file2.ext2
  dir2/
   file3.ext3
    dir3/
     file4.ext4

I want to achieve the following:

destination/
 dir1file1.ext1
 dir1file2.ext2
 dir2file3.ext3
 dir3file4.ext4

In other words, I want to move all the files, recursively, from source to destination, appending the original subdirectory name to the file name.

5

Using Perl rename and find:

$ find source -type f | rename -n 's:(^|.*/)([^/]*)/([^/]*)$:destination/$2$3:'
rename(source/dir2/file3.ext3, destination/dir2file3.ext3)
rename(source/dir2/dir3/file4.ext4, destination/dir3file4.ext4)
rename(source/dir1/file1.ext1, destination/dir1file1.ext1)
rename(source/dir1/file2.ext2, destination/dir1file2.ext2)

The regex (^|.*/)([^/]*)/([^/]*) saves the last two components of the path (the filename and parent directory) as the second and third matched groups.

The destination directory must exist before running this. The -n is for testing, remove it for actually moving the files.

|improve this answer|||||
  • Thank you very much. Your code does exactly what I asked for, and with a minor modification, exactly what I need. I forgot I'd want a separator between dir and file ($2-$3). Even I can do that. – Catweasel Jan 12 '17 at 4:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.