Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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

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.