How can I get the zsh extension with the dot included?
Example inputs and outputs desired:
'one.two'
- '.two'
'none'
- ''
I know I could test "Does this string have an extension?" with an if-statement, then if it does have an extension I can use ${var:e}
parameter expansion, but this is very verbose.
I'm sure there must be a shorter way to get the end of a file name.
The reason this is useful to me is so that I can generate new file names that have the same extensions as existing file names, even if those existing file names don't have extensions. I had previously tried
"${existing:r}-$count.${existing:e}"
But that doesn't work for existing file names that don't have extensions (it adds a dot at the end)
One possibility, based on this answer:
ext=${fname#$fname:r}
The :r
(root) expansion modifier will remove the dot and extension from the path. The code uses the ${name#pattern}
expansion to reverse that, and keep the part that was deleted. Some examples:
(){ for f; printf "%-7s -> '%s'\n" $f ${f#$f:r} } \
'one.two' 'none' 'just.' '/with/a dir.part/a b.c d'
#=> one.two -> '.two'
#=> none -> ''
#=> just. -> '.'
#=> /with/a dir.part/a b.c d -> '.c d'
Building a filename:
existing=file.ext; count=22
newName="${existing:r}-${count}${existing#$existing:r}"
typeset -p newName
#=> typeset newName=file-22.ext