I'm working on some stuff related to converting files, and I'm trying to find a shell command to remove the original file extension.
For example, if I convert a file called text.rtf
, it will be converted into text.rtf.mobi
. I'd like to use something to remove the .rtf (or any other extension) so it's only text.mobi
.
I've been playing with awk and sed but I couldn't get anything to work. I'm not sure how to get it to pick up both the original extension and the .mobi, but only remove the original extension.
Somewhat related, where should I be going to pick up regex and actually understand it instead of just immense amounts of Googling? Thanks.
EDIT: I was a little unclear in the original post so let me clarify. The shell command I need is for removing the original extension in a converted file, such as text.ANYTHING.mobi. Sorry about the confusion.
for f in *.mobi
do
mv $f $(echo $f | cut -d'.' -f1).mobi
done
Just remove all the extensions and then add back in .mobi
$ x=something.whatever.mobi
$ echo ${x%%.*}.mobi
something.mobi
The classic way is the basename
command:
file="text.rtf"
new=$(basename "$file" .rtf).mobi
The more modern way avoids exercising other programs:
file="text.rtf"
new="${file%.rtf}.mobi"
If you really must use awk
, then I suppose you use:
file="text.rtf"
new=$(echo "$file" | awk '/\.rtf$/ { sub(/\.rtf$/, ".mobi"); } { print }')
For sed
, you use:
file="text.rtf"
new=$(echo "$file" | sed 's/\.rtf$/.mobi/')
For a really good explanation of regular expressions, then you want Friedl's "Mastering Regular Expressions" book.
To convert text.rtf.mobi
to text.mobi
, you can use any of the tools previously shown with minor adaptations:
new=$(basename "$file" .rtf.mobi).mobi
new="${file%.rtf.mobi}.mobi"
new=$(echo "$file" | awk '/\.rtf\.mobi$/ { sub(/\.rtf\.mobi$/, ".mobi"); } { print }')
new=$(echo "$file" | sed 's/\.rtf\.mobi$/.mobi/')
And things are only marginally different if the .rtf
can be any other extension, but you start to ask yourself "why doesn't he remove the original extension from the file before converting it, or use the file naming facilities in the converter to get the required output name?"
There is no longer a sensible way to do it with basename
.
new="${file/.[!.]*.mobi/}" # bash
new=$(echo "$file" | awk '/\.[^.]+\.mobi$/ { sub(\.[^.]*\.mobi$/, ".mobi"); } { print }')
new=$(echo "$file" | sed 's/\.[^.]*\.mobi$/.mobi/')
Here's an example using xargs and basename to strip .wav from file names for batch conversion of wave files into mp3s using lame:
/bin/ls | xargs -I % basename % ".wav" | xargs -I $ lame --tl Xenologix --ta Drøn --tg IDM --tt $ $.wav $.mp3
for f in *.mobi
do
mv $f `echo $f|awk -F"." '{print $1"."$3}'`
done