Recursive copy files with rename

file-copyrecursiverename

If I have input folder files_input that has subfilders like 01-2015, 02-2015, 03-2015 etc and all these subfolders have other subfolders. Each subfolder has only one file called index.html.

How can I copy all these index.html files into one folder called files_output so that they end up like separate files in the same folder. They should ofcourse be renamed and I have tried to use –backup for that…

I have tried

find files_input -name \*.html -exec cp --backup=t '{}' files_output \;

to get them numbered but that copies only one file and nothing else.

I don't know does that change anything but I'm using zsh, here are the versions:

   $ zsh --version | head -1
   zsh 5.0.2 (x86_64-pc-linux-gnu)
   $ bash --version | head -1
   GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)
   $ cp --version | head -1
   cp (GNU coreutils) 8.21
   $ find --version | head -1
   find (GNU findutils) 4.4.2

Ideas?

Edit:

Trying to run e.g. following

cp --backup=t files_input/01-2015/index.html files_output

five times in a row still gives me one index.html in files_output folder! Is cp broken ? Why don't I have five different files?

Best Answer

As you're a zsh user:

$ tree files_input
files_input
|-- 01_2015
|   |-- subfolder-1
|   |   `-- index.html
|   |-- subfolder-2
|   |   `-- index.html
|   |-- subfolder-3
|   |   `-- index.html
|   |-- subfolder-4
|   |   `-- index.html
|   `-- subfolder-5
|       `-- index.html
|-- 02_2015
|   |-- subfolder-1
|   |   `-- index.html
|   |-- subfolder-2
|   |   `-- index.html
|   |-- subfolder-3
|   |   `-- index.html
|   |-- subfolder-4
|   |   `-- index.html
|   `-- subfolder-5
|       `-- index.html
(etc.)
$ mkdir -p files_output
$ autoload -U zmv
$ zmv -C './files_input/(*)/(*)/index.html' './files_output/$1-$2-index.html'
$ tree files_output
files_output
|-- 01_2015-subfolder-1-index.html
|-- 01_2015-subfolder-2-index.html
|-- 01_2015-subfolder-3-index.html
|-- 01_2015-subfolder-4-index.html
|-- 01_2015-subfolder-5-index.html
|-- 02_2015-subfolder-1-index.html
|-- 02_2015-subfolder-2-index.html
(etc.)

What's happening here is that we make the command zmv available with autoload -U zmv. This command is used for renaming, copying or linking files matching a zsh extended globbing pattern.

We use zmv with its -C option, telling it to copy the files (as opposed to moving them, which is the default). We then specify a pattern that matches the files we'd want to copy, ./files_input/(*)/(*)/index.html. The two (*) matches the two levels of subdirectory names, and we put them within parentheses for use in the new name of each file. The new name of each file is the second argument, ./files_output/$1-$2-index.html, where $1 and $2 will be the strings captured by the parentheses in the pattern, i.e. back-references to the subdirectory names. Both arguments should be single quoted.

Related Question