recursively add directory name to file name

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.

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

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.

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply