I want to get the filename (without extension) and the extension separately.
The best solution I found so far is:
NAME=`echo "$FILE" | cut -d'.' -f1`
EXTENSION=`echo "$FILE" | cut -d'.' -f2`
This is wrong because it doesn't work if the file name contains multiple .
characters. If, let's say, I have a.b.js
, it will consider a
and b.js
, instead of a.b
and js
.
It can be easily done in Python with
file, ext = os.path.splitext(path)
but I'd prefer not to fire up a Python interpreter just for this, if possible.
Any better ideas?
You could use the
cut
command to remove the last two extensions (the".tar.gz"
part):As noted by Clayton Hughes in a comment, this will not work for the actual example in the question. So as an alternative I propose using
sed
with extended regular expressions, like this:It works by removing the last two (alpha-numeric) extensions unconditionally.
[Updated again after comment from Anders Lindahl]
Smallest and simplest solution (in single line) is:
How to extract the filename and extension in fish:
Caveats: Splits on the last dot, which works well for filenames with dots in them, but not well for extensions with dots in them. See example below.
Usage:
There's probably better ways to do this. Feel free to edit my answer to improve it.
If there's a limited set of extensions you'll be dealing with and you know all of them, try this:
This does not have the caveat as the first example, but you do have to handle every case so it could be more tedious depending on how many extensions you can expect.
You can force cut to display all fields and subsequent ones adding
-
to field number.So if FILE is
eth0.pcap.gz
, the EXTENSION will bepcap.gz
Using the same logic, you can also fetch the file name using '-' with cut as follows :
This works even for filenames that do not have any extension.
Based largely off of @mklement0's excellent, and chock-full of random, useful bashisms - as well as other answers to this / other questions / "that darn internet"... I wrapped it all up in a little, slightly more comprehensible, reusable function for my (or your)
.bash_profile
that takes care of what (I consider) should be a more robust version ofdirname
/basename
/ what have you..Usage examples...
Magic file recognition
In addition to the lot of good answers on this Stack Overflow question I would like to add:
Under Linux and other unixen, there is a magic command named
file
, that do filetype detection by analysing some first bytes of file. This is a very old tool, initialy used for print servers (if not created for... I'm not sure about that).Standards extensions could be found in
/etc/mime.types
(on my Debian GNU/Linux desktop. Seeman file
andman mime.types
. Perhaps you have to install thefile
utility andmime-support
packages):You could create a bash function for determining right extension. There is a little (not perfect) sample:
This function could set a Bash variable that can be used later:
(This is inspired from @Petesh right answer):