fish shell: Is it possible to conveniently strip extensions?

If you know the extension (eg _bak, a common usecase) this is possibly more convenient:

for f in (ls *_bak)
    mv $f (basename $f _bak)
end

Nope. fish has a much smaller feature set than bash, relying on external commands:

$ set filename foo.bar.baz
$ set rootname (echo $filename | sed 's/\.[^.]*$//')
$ echo $rootname
foo.bar

You can strip off the extension from a filename using the string command:

echo (string split -r -m1 . $filename)[1]

This will split filename at the right-most dot and print the first element of the resulting list. If there is no dot, that list will contain a single element with filename.

If you also need to strip off leading directories, combine it with basename:

echo (basename $filename | string split -r -m1 .)[1]

In this example, string reads its input from stdin rather than being passed the filename as a command line argument.

Tags:

Fish