3

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.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
Tom
  • 5,835
  • 4
  • 25
  • 30
  • this has already been answered: http://stackoverflow.com/questions/2171966/bash-rename-extension-recursive – alfredodeza Aug 05 '10 at 13:01
  • @alfredodeza: Thanks for pointing that one out - I can't find anything there (other than shell scripts) which do what I want though. Some good answers below, however. – Tom Aug 05 '10 at 13:12

4 Answers4

3

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
  • 48,066
  • 12
  • 84
  • 109
  • +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 Aug 05 '10 at 13:12
  • 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 Aug 05 '10 at 13:16
  • 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 Aug 05 '10 at 13:21
0
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
  • 2,724
  • 4
  • 37
  • 58
0

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
  • 8,833
  • 3
  • 35
  • 41
0
find /fullpath -type f -name "*.dev"|sed 's|\(.*\)\(\.pdf\)|mv & \1.sometag|' | sh
ghostdog74
  • 327,991
  • 56
  • 259
  • 343