4

I'm trying to convert files from this structure:

foldera/folderb/filec.png

to:

foldera_folderb_filec.png

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?

1

This might work for you:

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

Where:

  • %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.

Warning:

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

  • 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
1

This worked well for me. It eliminates the ._ prefix, but is otherwise the same as potong's answer.

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

Some great answers above but I'll put mine just in case as well.

This will just echo out the mv commands:

find . -type f -exec sh -c 'for f do x=${f#./}; y="${x// /_}"; echo "mv ${x// /\ } ${y////-}"; done' {} +

This will just echo out the mv commands into your pasteboard directly:

find . -type f -exec sh -c 'for f do x=${f#./}; y="${x// /_}"; echo "mv ${x// /\ } ${y////-}"; done' {} + | pbcopy

[Careful] This will immediately run the mv commands for you:

find . -type f -exec sh -c 'for f do x=${f#./}; y="${x// /_}"; eval "mv ${x// /\ } ${y////-}"; done' {} +
New contributor
xemacobra is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.