Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I've got a simple command that does almost what I want. The following will locate all files with a suffix of '_compressed.swf' and copy each into its same directory with a '.bak2' appended:

find '../content' -name '*_compressed.swf' -print0 | xargs -0 -I {} cp {} {}.bak2

Results
In: /content/somefile_compressed.swf
Out: /content/somefile_compressed.swf.bak2

However, I need to replace '_compressed.swf' with '_content.swf' I'd like to use find, rather than recursive flag on cp for consistency.

Objective
In: /content/somefile_compressed.swf
Out: /content/somefile_content.swf

share|improve this question
1  
Cross-posted here: serverfault.com/questions/115880/… –  Dennis Williamson Feb 23 '10 at 18:38

3 Answers 3

up vote 3 down vote accepted

This solution is probably the most portable:

find "../content" -name "*_compressed.swf" -exec sh -c 'cp {} `dirname {}`/`basename {} compressed.swf`content.swf' \;

There is also the famous rename.pl script which is distributed with Perl, and the rename command which could have made this a bit easier. These aren't available on all distributions though, these commands are for the most part.

share|improve this answer
    
The above moves the files from their current location to the script's location and adds the suffix 'content.swf'. Replacing mv with cp gets me closer, but I still need replace text in name rather than append. I'm getting closer by using sed, but still learning. –  Michael Prescott Feb 23 '10 at 22:00
    
@Michael you're right! whoops. I was only testing in the current directory hence why it worked for me. I've fixed it :) –  John T Feb 24 '10 at 4:19
    
Hey, thanks John. I like it. Much of this is all new to me. I understand usage of find, -exec, sh, dirname {}, basename {}, but I'm a little confused about the combined usage. sh -c ' ' converts the string into a command and runs the command, right? mv {} expands into one of find results "mv ../content/file1of20_compressed.swf ???????" It's the second part of that which I don't understand yet. What is causing the compressed.swf to be replaced by content.swf? In my solution you can see I just learned how to use sed. –  Michael Prescott Feb 24 '10 at 17:53
1  
@Michael what's happening is the file is being moved with a new name. If {} contained /etc/somefile_compressed.swf, dirname takes /etc and basename {} compressed.swf will leave you with somefile_. Now you put these 2 together with the slash I added in the middle (/) and you have /etc/somefile_. You'll notice I added content.swf to the end so it completes the statement as /etc/somefile_content.swf. HTH. –  John T Feb 24 '10 at 22:54
    
i'd use rename.pl if mv functionality was desired (it's not hard to add to any system with Perl) but the cp makes this a different beast. you'd have to tweak the script to do a copy instead of rename, which would work, but is more work. @John - nice find solution; it's big and long and ugly, but it looks like it would work. (don't ask me to help test it tho!) :) –  quack quixote Feb 24 '10 at 23:45

I'm sure this all can be handled in one line. I got really close to a one line solution and with some help even closer, but no success. The following works:

#!/bin/bash

# Read all file names into an array
FilesArray=($(find "../content" -name "*_compressed.swf"))

# Get length of an array
FilesIndex=${#FilesArray[@]}


# Use for loop read all directory names
for (( i=0; i<${FilesIndex}; i++ ));
do
    source="${FilesArray[$i]}"
    destination="$(echo "${source}" | sed 's/compressed/content/')"
    cp "${source}" "${destination}"
done

exit 0;
share|improve this answer

I believe this should do the trick and is collapsible to a one liner if you really really need to ;)

find ../content -name '*_compressed.swf' | while read file
do
cp "$file" "${file/_compressed.swf/_content.swf}"
done

Bash pattern substitution works nicely in these cases.

share|improve this answer

Your Answer

 
discard

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.