Skip to content
shellhacks.dev
Bash

Strip a file extension

Strip a file extension in Bash with ${f%.*}, which removes only the shortest suffix after the last dot and needs no basename call or subshell.

1 min read
Summarize in AI

You have a file name in a variable and want it without the extension, and you would rather not fork basename or sed to get it.

Shell
f=archive.tar.gz
printf '%s\n' "${f%.*}"
f=Makefile
printf '%s\n' "${f%.*}"
f=.bashrc
printf '[%s]\n' "${f%.*}"
Text
archive.tar
Makefile
[]

${var%pattern} removes the shortest match of the pattern from the end of the value, and .* matches a dot followed by anything, so only the last suffix goes. A name with no dot is returned unchanged, which is usually what you want. The operator is part of shell parameter expansion and runs inside the shell, so there is no process to start.

A name that begins with a dot and has no other, like .bashrc, loses everything and leaves an empty string, as the last line of output shows. Guard for that case when the input can be a dotfile. The same expansion works in any POSIX shell.

Share

More snippets

Bash

Strip every extension from a name

Remove every extension from a name with ${f%%.*} in Bash. The doubled percent sign takes the longest match, where a single one stops at the last dot.

1 min read

Get new posts by email

One email when a new post is published. No spam.

Unsubscribe in one click. No spam, ever.