Bash Parameter Expansion

I have made the following examples that print various parameter expansions

text: iv-hhz-sac/hpac/hhz.d/iv.hpac..hhz.d.2016.250.070018.sac
(text%.*):  iv-hhz-sac/hpac/hhz.d/iv.hpac..hhz.d.2016.250.070018
(text%%.*): iv-hhz-sac/hpac/hhz
(text#*.):  d/iv.hpac..hhz.d.2016.250.070018.sac
(text##*.): sac
(text##*/): iv.hpac..hhz.d.2016.250.070018.sac

Is there a way to get the filename without the directory and without the extension,
using parameter expansion to get

  iv.hpac..hhz.d.2016.250.070018

---------- Post updated at 02:59 PM ---------- Previous update was at 02:41 PM ----------

The following does not work for example

${${text##*/}%.*}

You have already shown us that you know how to get what you want:

text="iv-hhz-sac/hpac/hhz.d/iv.hpac..hhz.d.2016.250.070018.sac"
result=${text%.*}
result=${result##*/}
printf '%s\n' "$result"

which, as requested, produces the output:

iv.hpac..hhz.d.2016.250.070018
1 Like

Yes, but it would be cumbersome and plain ugly. Writing scripts (i suppose you need it in a script) is all about clarity and making it easy to understand what is done, therefore you should do it in two steps using the expansions you already found. I would write it like this:

text="${text##*/}"      # cut off the path
text="${text%.*}"       # cut off the extension

For completeness' (but again: don't really do it! This is just to show off my prowess in writing incomprehensible code! :wink: ) sake: you can use an expansion inside another expansion as a pattern. For instance, this cuts off the first character in a string, notice the nested expansion:

chLine="abcdefghi"

while [ -n "$chLine" ] ; do
     chChar="${chLine%${chLine#?}}"        # nested expansion!!
     chLine="${chLine#?}"

     echo char is: \"$chChar\"
     echo line is: \"$chLine\"
done

Using this device you could do what you want. Don't!

I hope this helps.

bakunin

2 Likes