Super User is a question and answer site for computer enthusiasts and power users. 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'm trying to convert files from this structure:




I'm halfway there:

 find . -type f -name "*.png" | sed 's@^./@@g;s@/@-@g'

which basically converts the name structure. However, it doesn't do the copy yet. At this point I'm stuck. How can I expand on the script to actually perform the copy operations?

share|improve this question
up vote 1 down vote accepted

This might work for you:

find . -type f -name "*.png" | sed 'h;y/\//_/;H;g;s/\n/ /g;s/^/cp -v /' | sh
share|improve this answer
wow.great. This basically works, except that all files start with '._' – reinier Mar 17 '12 at 11:58
find -type f -name '*.png' -printf '%P\0' | \
while read -d $'\0' i ; do cp "$i" "${i////_}" ; done


  • %P tell find to omit the leading ./;

  • \0 tell find to print the paths using the ASCII NUL character as separator (this should avoid problems with strange names);

  • -d $'\0' tell bash to use the proper delimiter for reading the paths;

  • ${i////_} tell bash to replace every occurrences of / with _ in the path.


This pipeline may involve file overwrites, make sure to take the proper precautions.

share|improve this answer
find: illegal option -- t. find: illegal option -- y. find: illegal option -- p. find: illegal option -- e. find: -printf: unknown option =( Should I have told you I'm on a Mac? – reinier Mar 17 '12 at 11:57

This worked well for me. It elminates the ._ prefix.

find . -type f -name "*" | sed 's/$/"/;s/^/"/;h;s/^...//;s/^/"/;y/\//_/;H;g;s/\n/ /g;s/^/cp -v /'
share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .