views:

92

answers:

6

I'm trying to find a bash script that will recursively look for files with a .bx extension, and remove this extension. The filenames are in no particular format (some are hidden files with "." prefix, some have spaces in the name, etc.), and not all files have this extension.

I'm not sure how to find each file with the .bx extension (in and below my cwd) and remove it. Thanks for the help!

+1  A: 
find . -name '*.bx' -type f | while read NAME ; do mv "${NAME}" "${NAME%.bx}" ; done
tylerl
`"${NAME}" "${NAME%.bx}"` is better. File names might contain spaces!
Benoit
@Benoit thanks. Forgot that.
tylerl
This is perfect, thanks. After looking around, I believe that you can also do it using regex in find, i.e.find . -type f -regex '.*\.bx$' | while read i; do mv "$i" "${i%%.bx}"; done
nick
+1  A: 

Assuming you are in the folder from where you want to do this

find . -name "*.bx" -print0 | xargs -0 rename .bx ""
Raghuram
Now safely handles spaces.
tylerl
syntax error at (eval 1) line 1, near "."xargs: rename: exited with status 255; aborting
Ken
@tylerl - thanks
Raghuram
@Ken It works when I run it.
tylerl
+1  A: 
find -name "*.bx" -print0 | xargs -0 rename 's/\.bx//'
Ken
Does not work for me (no effect). The version of `rename` shipped on Linux (centos 5.5) does not support regular expressions. See Raghuram's answer for a working solution.
tylerl
Seems to depend of the version then - man rename gives me "perl v5.10.1" (on Ubuntu 10.04.1)
Ken
Sorry, should've mentioned I'm on OS X, which unfortunately doesn't ship with rename. Your solution looks good for linux users.
nick
+1  A: 

Bash 4+

shopt -s globstar
shopt -s nullglob
shopt -s dotglob

for file in **/*.bx
do
  mv "$file" "${file%.bx}"
done
ghostdog74
+1  A: 

for blah in *.bx ; do mv ${blah} ${blah%%.bx}

jyzuz
just missing `; done` at the end ;)
Skidgirl
A: 

Here is another version which does the following:

  1. Finds out files based on $old_ext variable (right now set to .bx) in and below cwd, stores them in $files
  2. Replaces those files' extension to nothing (or something new depending on $new_ext variable, currently set to .xyz)

The script uses dirname and basename to find out file-path and file-name respectively.

#!/bin/bash

old_ext=".bx"
new_ext=".xyz"

files=$(find ./ -name "*${old_ext}")

for file in $files
do
    file_name=$(basename $file $old_ext)
    file_path=$(dirname $file)
    new_file=${file_path}/${file_name}${new_ext}

    #echo "$file --> $new_file"
    mv "$file"    "$new_file"
done
Babil