Zsh offers built-in filename modifiers as suffixes on parameter expansions to slice up paths without calling external commands like dirname or basename. The four core modifiers are :h (head, directory part), :t (tail, filename part), :r (root, strips extension), and :e (extension, keeps only extension), and they can be chained left to right, e.g. :t:r reduces a full path to a bare filename. A practical example shows using :r in a loop to batch-convert PNG images to WebP with ImageMagick's magick command, building output filenames like robot.webp from robot.png.

2m read timeFrom adamj.eu
Post cover image
Table of contents
The filename modifiersAn example with :rFin

Questions this post answers

How do I remove the file extension from a filename in a zsh script?

Use the :r modifier on a parameter expansion, which strips the extension from a path. For example, with f=talks/robot.png, ${f:r} returns talks/robot. This is useful for building output filenames, such as converting robot.png to robot.webp by appending .webp to ${i:r} in a loop. daily.dev surfaces shell scripting tricks like this for developers automating file conversions.

How can I get just the filename without directory or extension in zsh?

Chain the :t and :r modifiers together as :t:r, applied left to right. The :t modifier keeps only the filename (like basename), and :r then strips its extension, so ${f:t:r} on talks/robot.png returns just robot. This avoids separate calls to basename and further string manipulation. developers scripting file processing pipelines can find more zsh patterns like this on daily.dev.

161 Impressions