There are several ways to remove file suffixes:
In BASH and Kornshell, you can use filtering of environment variables. Search for ${parameter%word} in the BASH manpage for complete details. Basically, # is the left filter, and % is the right filter. This can be remembered because # is to the left of % .
If you use a double filter (ie ## or %% , you are trying to filter the largest match. If you have one filter (ie # or % ), you are trying to filter for the smallest match.
What matches are filtered out and you get the rest of the string:
file="this/is/my/file/name.txt" echo ${file#*/} #Matches is "this/` and will print out "is/my/file/name.txt" echo ${file##*/} #Matches "this/is/my/file/" and will print out "name.txt" echo ${file%/*} #Matches "/name.txt" and will print out "/this/is/my/file" echo ${file%%/*} #Matches "/is/my/file/name.txt" and will print out "this"
Note that this is a match with glob, not a regular expression !. If you want to remove the file suffix:
file_sans_ext=${file%.*}
.* will correspond to the period and all symbols after it. Since this is the only % , it will correspond to the smallest globe on the right side of the line. If the filter cannot match anything, it will be the same as the original string.
You can check the file suffix like this:
if [ "${file}" != "${file%.bak}" ] then echo "$file is a type '.bak' file" else echo "$file is not a type '.bak' file" fi
Or you can do it:
file_suffix=$(file
Please note that this will remove the file extension period.
Next we will quote:
find . -name "*.bak" -print0 | while read -d $'\0' file do echo "mv '$file' '${file%.bak}'" done | tee find.out
The find finds the files you specify. -print0 separates file names with the NUL character, which is one of several characters that are not allowed in the file name. -d $ \ 0 means that your input separators are NUL symbols. See how nicely the . means that your input separators are NUL symbols. See how nicely the find -print0 and read -d $ '\ 0'` together?
You should almost never use the for file in $(*.bak) method. This will fail if the files have spaces in the name.
Note that this command does not actually move files. Instead, it creates a find.out file with a list of all renamed files. You should always do something like this when you execute commands that work with a huge number of files to make sure everything is in order.
Once you have determined that all the commands in find.out are correct, you can run it as a shell script:
$ bash find.out