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.
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.