Search code examples
bashshellparameter-expansion

How to remember which expansion ${var%} ${var#} work from which end?


I am having trouble remembering which one of the parameter expansions ${var%subst} or ${var#subst} remove from the front and which one from the back of the string. Example:

$ var=/a/b/c
$ echo dirname=${var#/*} filename=${var%%*/}
dirname=a/b/c filename=/a/b/c                      # Wrong!
$ echo dirname=${var%/*} filename=${var##*/}
dirname=/a/b filename=c

I always mix them and either end up writing some test commands or checking the manual. It's easy to remember that %% removes more then %, because %% is a longer string then %, 2 characters vs 1 character, same for ## vs #. But I always mix % with #.

Is there a memory rule to know which % or # remove from which end of the string?


Solution

  • I use a figurative representation of the symbols:

    • %: Looks like a pair of scissors to cut the right part of a text strip while you hold the scissors in your right hand and the strip in your left hand.

    • #: Looks like an eraser you use to erase the left part of a text strip while you hold the right part with your right hand and the eraser in your left hand.

    • //: This bash specific text-replace, looks like the cuts in a strip to re-assemble or edit in-between parts.