Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a .bdf file inside subfolders. All the .bdf have the same name: Loads.bdf



I need to find (and copy to a new folder) all Load.bdf files and rename them with its path name.

Example: After the intended operation, it should show something like this.

share|improve this question

I would use the mcp tool from the mmv ("multiple move") package for that:

mcp '/home/user/*/*/Load.bdf' '#1_#2_Load.bdf'

The #1, #2 etc. in the second string will be replaced by the contents of the corresponding 1st, 2nd etc. wildcard from the first string. Note that the path is in single quotes so that the wildcards are interpreted by mcp, not by the shell.

With the command shown, the files will be copied to the current directory. If you replace mcp with mmv, the files will be moved instead.

share|improve this answer
Double quoted strings also don't have wildcard expansion, at least in bash. – Daniel Beck Jun 17 '14 at 0:04
This was useful to me to copy the name of the folder to each file mmv '*/*.m4a' '#1.m4a' – Arturo Jul 1 at 7:33

Using prename (aliased to rename on many systems) it is possible to do this without multiple runs of mv or cp:

cd /home/user
find . -type f -name 'Loads.bdf' -exec \
  prename -n 's:^./::; s:/:_:g; s:^:destination/:' {} +

Remove the -n when you are sure this is moving the files you want.


To copy the files instead of moving them, the fastest way is to copy first with cpio or pax, then to rename as before. Eg (with GNU cpio):

cd /home/user
find . -type f -name 'Loads.bdf | cpio -p --make-directories destination

cd destination
find . -type f -name 'Loads.bdf' -exec  prename -n 's:^./::; s:/:_:g' {} +

Note that while pax is both POSIX and LSB and cpio is no longer POSIX, cpio is still the program which is commonly found many systems.

To handle filenames with newlines with GNU find/cpio it is possible to add -print0 to find and -0 to cpio.

Update 2

The pax solution is a one-liner (not including the cd):

cd /home/user
find . -name 'Loads.bdf' | cut -d/ -f 2- | pax -rws ':/:_:g' destination

Or for any filename (and GNU find):

find /home/user -name 'Loads.bdf' -printf '%P\0' | pax -0rws ':/:_:g' destination
share|improve this answer
There are two renames, the perl one (aka prename, but called rename by default in Ubuntu at least), and the other one that doesn't use regex (known as rename on Arch and Red Hat). Also, -execdir is preferred to -exec (see man find). Finally, doesn't this command move the files, not copy them? – Sparhawk Jun 16 '14 at 15:15
@Sparhawk, yes that's why I specified prename. Although I missed the 'copy` part in the question. – Graeme Jun 16 '14 at 15:17
Ah okay (was that an edit?). Perhaps I just read it wrong. – Sparhawk Jun 16 '14 at 15:17
@Sparhawk, no edit. Good call on the move vs copy though I have added an updated solution now. – Graeme Jun 16 '14 at 15:35
@Tim, updated with the pax solution, it has its own find/replace option. – Graeme Jun 16 '14 at 15:57

If you happen to need to do this on a system that doesn't have the tools mentioned in some of the other answers (like mcp and mmv, or prename), and you want to do it entirely in the shell, you can do something like:

#!/usr/bin/env bash


for file in $(find $oldpath -type f -name Load.bdf); do
        if [ -f $newname ]; then
                echo "$newname already exists."
                echo "copy: $file"
                echo "  --> $newname"
                cp $file $newname

This script will find all the files named Load.bdf in the oldpath directory, munge the directory names into a new filename, and copy them to your destination directory. We can also check for the existence of files already copied, in case you need to run it more than once, and we don't need to copy all the files again.

The resulting directory structure would end up looking like:

bash$ find . -type f
share|improve this answer
thank you all for your information. i got lot more information than what i need. thank you again. – sh999 Jun 16 '14 at 18:39

In zsh, it's easy with zmv.

autoload -U zmv
cd /home/user
zmv '*/*/*' '${1//\//_}'
share|improve this answer
env - sh <<\SCRIPT

    t=/home/user/target f=folder
    cd "${t%/*}" && mkdir -p "$t"
    set -- $f??/$f???/Load.BDF
    while [ -e "$1" ] ; do
        cp "$1" "$t/$(IFS=/
            printf '%s_%s_%s\n' $1)"
    shift ; done


I think this is all fully portable shell script - and it's pretty simply done, though I had my doubts at first.

share|improve this answer

Your Answer


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.