0

I was reviewing this post: Split a string by some separator in bash?

In my scenario, I tried to use just Bash to accomplish this, but I'm running into some weird behavior.

shopt -s extglob
export var=abc_def__123__456
echo ${var/%__*}
echo ${var/#!(__)__}
shopt -u extglob

The first echo is working as expected and outputs abc_def. I'm expecting the second echo to output 123__456 and instead, it outputs 456. This is not working the way I'm reading the manual, which says:

If pattern is preceded by ‘#’ (the third form above), it must match at the beginning of the expanded value of parameter.

To me, this means that when it gets to the first occurrence of __, the match should stop and so the second echo should return 123__456, which is desired.

What am I missing?

Kusalananda
  • 333,661
Hossy
  • 25

1 Answers1

2

With any POSIX shell, using standard parameter expansion:

var="abc_def__123__456"
echo "${var%%__*}"
echo "${var#*__}"

Output:

abc_def
123__456
Kusalananda
  • 333,661
Cyrus
  • 12,309
  • Ok, I saw that and didn't know if * was going to be greedy like .* is in regex. – Hossy Mar 27 '23 at 21:54
  • Ah, but I guess that's what # signifies (not greedy/shortest match) and %% makes it greedy from the right to left. Thank you! – Hossy Mar 27 '23 at 21:59
  • @Hossy # and % removes the shortest prefix and suffix string (respectively) matching the given shell pattern. If you double them up as %% and ##, they remove the longest prefix and suffix string matched by the given pattern. – Kusalananda Mar 28 '23 at 07:38