views:

124

answers:

4

When we develop locally, we append ".dev" or ".prod" to files that should be made available only to the development/production server respectively.

What I would like to do is; after deploying the site to the server, recursively find all files with the ".dev" suffix (for example) and remove it (renaming the file). How would I go about doing this, preferably entirely in the shell (without scripts) so I can add it to our deployment script?

Our servers run Ubuntu 10.04.

A: 
for file in `ls *.dev`; do echo "Old Name $file"; new_name=`echo $file | sed -e 's/dev//'` ; echo "New Name $new_name"; mv $file $new_name; done

In an example of something I used recently this code looks for any file that ends with new.xml changes a date in the filename (filenames were of the form xmlEventLog_2010-03-23T11:16:16_PFM_1_1.xml), removes the _new from the name and renames the filename to the new name :

for file in `ls *new.xml`; do echo "Old Name $file"; new_name=`echo $file | sed -e 's/[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}/2010-03-23/g' | sed 's/_new//g'` ; echo "New Name $new_name"; mv $file $new_name; done

Is this the type of thing you wanted?

amadain
That doesn't recurse into subdirectories.
bcat
And it doesn't work with filenames containing anything "special" (spaces, newlines, nonprintable characters...).
Philipp
just trying to help. won't bother doing that on this site again
amadain
Dude, chill. We were trying to help you improve your answer, which doesn't actually answer the original question. It's not a personal attack on you.
bcat
why was it voted down then?
amadain
Because it's not correct. (And I didn't downvote it, for what it's worth.)
bcat
A: 

It's totally untested, but this should work in the POSIX-like shell of your choice:

remove-suffix () {
    local filename
    while read filename; do
        mv "$filename" "$(printf %s "$filename" | sed "s/\\.$1\$//")"
    done
}

find -name '*.dev' | remove-suffix .dev

Note: In the very unusual case that one or more of your filenames contains a newline character, this won't work.

bcat
+2  A: 

Try this (not entirely shell-only, requires the find and mv utilities):

find . '(' -name '*.dev' -o -name '*.prod' ')' -type f -execdir sh -c 'mv -- "$0" "${0%.*}"' '{}' ';'

If you have the rename and xargs utilities, you can speed this up a lot:

find . '(' -name '*.dev' -o -name '*.prod' ')' -type f -print0 | xargs -0 rename 's/\.(dev|prod)$//'

Both versions should work with any file name, including file names containing newlines.

Philipp
+1, that's better than mine. If you have really strict compatibility needs, though, you might want to be aware that POSIX `find` doesn't have `-execdir` or `-print0`, and I believe `"${0%.dev}"` is a bashism.
bcat
This seems to work well; I replaced 's/\.dev$/.prod/' with 's/\.dev$//' as I'm looking to completely remove the extension. There are no particular compatibility needs, so the dependency on rename/xargs isn't a problem. Thanks!
Tom
The manpage of `sh` says that `sh` knows about suffix removal. `-execdir` could be replaced by `-exec` (which the Linux manpage says is less secure), but `-print0` is impossible to replace.
Philipp
@Tom: Sorry, I misread the question.
Philipp
A: 
find /fullpath -type f -name "*.dev"|sed 's|\(.*\)\(\.pdf\)|mv & \1.sometag|' | sh
ghostdog74