For a fixed extension, the basename
utility could be used to do this:
$ f=/home/test/domain/example.txt
$ basename -- "$f" .txt
example
But since you have arbitrary extensions, you need to explicitly pick the last extension to pass to basename
. The shell's parameter expansions can be used here:
$ basename -- "$f" ".${f##*.}"
example
Or, while we're at it, use parameter expansions for both removals.
$ x="${f##*/}"; x="${x%.*}"; echo "$x"
example
${var##pattern}
takes var
with the longest prefix matching pattern
removed. With %%
it takes the suffix instead, and with one #
or %
the shortest prefix or suffix.
If you consider something like .txt.gz
a single expansion to be removed, you could use x="${x%%.*}"
(with a double %%
) instead.
Note that the last solution will give an empty string as output, if the given path ends in a /
, while basename
would ignore trailing slashes. The other case that needs care is where the directory names can also contain dots, so something like /home/test/domain.orig/example.txt.gz
, or where the filename contains no dots at all. (I didn't double check all those cases.)
For discussion on related issues, see:
zsh
(and even csh/tcsh where the feature comes from though you wouldn't want to use those these days):$file:t:r
(root name of the tail of the file). That's also available invim
.bash
has it for history substitution (likeecho !:$:t:r
for the root of tail of last word in previous command line) but not parameter expansion unfortunately. – Stéphane Chazelas Nov 03 '20 at 17:16