C0ppert0p
C0ppert0p

Reputation: 702

backtick not working

I have a large number of files in a directory structure I want to rename.

The file names are in this format:
"aaaaaa-bbbbbb_cccccc-ddddd_eeeee-fffff-ggggg-hhhhh.psd"

I want them in this format:
"Aaaaaa-Bbbbbb_Cccccc-Ddddd_Eeeee-Fffff-Ggggg-Hhhhh.psd

A single find and sed routine should transform them into the correct format:

find . -name "*psd" -exec sh -c "echo 'cp '{} `echo {} | sed 's/\([_-][a-z]\)\([A-Z]*\)/\2\U\1/g'`" \;

But it doesn't work:

input:

Assisted-or-Auto/Abstract-Render/assisted-or-auto_abstract-render_tiny-bubbles3.psd

output:

cp ./Assisted-or-Auto/Abstract-Render/assisted-or-auto_abstract-render_tiny-bubbles3.psd ./Assisted-or-Auto/Abstract-Render/assisted-or-auto_abstract-render_tiny-bubbles3.psd

The sed routine works if I remove the backtick and insert a semi-colon.

find . -name "*bubbles3.psd" -exec sh -c "echo 'cp '{} ; echo {} | sed 's/\([_-][a-z]\([A-Z]*\)/\2\U\1/g'" \;

cp ./Assisted-or-Auto/Abstract-Render/assisted-or-auto_abstract-render_tiny-bubbles3.psd
./Assisted-Or-Auto/Abstract-Render/assisted-Or-Auto_Abstract-Render_Tiny-Bubbles3.psd

So, for some reason backtick is not do what it should be doing. Any ideas on how I can resolve this issue? fyi replacing backticks with the " $(cmd) " notation has the same effect

Thanks

Upvotes: 0

Views: 1575

Answers (5)

potong
potong

Reputation: 58430

This might work for you:

find . -name "*bubbles3.psd" | 
sed 'h;s/\(^\|[/_-]\)./\U&/g;H;g;s/^/cp -v /;s/\n/ /' |
bash

If you want to see the cp command prior to execution, just leave off the last pipe | bash

Upvotes: 0

0xC0000022L
0xC0000022L

Reputation: 21289

Avoid backticks, as that means you're asking for escaping issues.

As was already pointed out, it is likely that the backticks take effect before the invocation of find.

Use $(), which can be nested without much escaping trouble and then escape the $ in $(command) so that it will survive the invocation and get passed to find. From that point on (assuming that find uses a shell - e.g. $SHELL - to execute your command) things will work fine.

Upvotes: 0

glenn jackman
glenn jackman

Reputation: 246837

slight variation

$ input=Assisted-or-Auto/Abstract-Render/assisted-or-auto_abstract-render_tiny-bubbles3.psd
$ sed 's!\(/\|-\|_\)[a-z]!\U&!g' <<< "$input"
Assisted-Or-Auto/Abstract-Render/Assisted-Or-Auto_Abstract-Render_Tiny-Bubbles3.psd

can be made a little cleaner with GNU sed

$ sed 's!(/|-|_)[a-z]!\U&!g' <<< "$input"

Upvotes: 0

bta
bta

Reputation: 45057

Most likely, the shell is interpreting the command inside the backticks first (even before running find). However, "{}" won't have any special meaning until after find runs. Try creating a shell function or bash script for your command instead of writing it inline. That should let you do more complex things without worrying about problems with shell escapes.

Upvotes: 2

shellter
shellter

Reputation: 37288

try

sed 's/\([/_-][a-z]\)\([A-Z]*\)/\2\U\1/g'

i.e.

echo $'./Assisted-or-Auto/Abstract-Render/assisted-or-auto_abstract-render_tiny-bubbles3.psd' \
| sed 's/\([/_-][a-z]\)\([A-Z]*\)/\2\U\1/g'

output

./Assisted-Or-Auto/Abstract-Render/Assisted-Or-Auto_Abstract-Render_Tiny-Bubbles3.psd

I only added the '/' to match the initial lowercase word-part (and my sed said mismatched \( .. \) so I added them 1 in in the logical place.

I hope this helps.

Upvotes: 0

Related Questions