By pr0nk


2019-10-08 10:40:12 8 Comments

Why does the following code produce different output in ksh and bash

p="folderA/folderB/folderC"
echo ${p%%+([^/])}
echo ${p#${p%%+([^/])}}

ksh outputs:

folderA/folderB/
folderC

bash outputs:

folderA/folderB/folderC

I'm especially confused because I used the bash documentation to create this parameter expansion.

I want to extract the folder name after the last slash. I found another way which is working in ksh and bash:

echo ${p##*/}

but I would like to understand why the first approach is not working.

2 comments

@oguz ismail 2019-10-08 10:59:44

+(...) is extended glob syntax, you need to enable extglob feature for bash to understand it. And as stated in the other answer, normally a circumflex shouldn't be used for negating a character class. Bash tolerates this mistake, but anyways let's use the correct syntax for the sake of portability:

shopt -s extglob
p="folderA/folderB/folderC"
echo "${p%%+([!/])}"
echo "${p#${p%%+([!/])}}"

yields:

folderA/folderB/
folderC

Related link: Bash Reference Manual § Pattern Matching.


And btw, you don't really need extended globs for this.

p="folderA/folderB/folderC"
echo "${p%${p##*/}}"
echo "${p##*/}"

Above script works just as well on any POSIX-compliant shell.

@mirabilos 2019-10-09 13:57:09

Another, more standards-compliant, Korn shell actually outputs

folderA/folderB/folderC

followed by an empty line. This is because shell globs are not regular expressions, and the character class negotiation operator is a false friend.

In POSIX shell, [^/] is actually unspecified but normally (["^"/] is more clear) means “either ^ or /” but you will want “anything that’s not /” which, in POSIX shell globs, is [!/] instead.

See the other answer for an explanation on how GNU bash needs shopt -s extglob to support Korn shell-compatible extended globbing patterns in addition.

Related Questions

Sponsored Content

22 Answered Questions

[SOLVED] How to check if a string contains a substring in Bash

  • 2008-10-23 12:37:31
  • davidsheldon
  • 1848280 View
  • 2279 Score
  • 22 Answer
  • Tags:   string bash substring

25 Answered Questions

[SOLVED] Set a default parameter value for a JavaScript function

36 Answered Questions

[SOLVED] Check if a directory exists in a shell script

  • 2008-09-12 20:06:25
  • Grundlefleck
  • 2681012 View
  • 3523 Score
  • 36 Answer
  • Tags:   shell unix posix

63 Answered Questions

[SOLVED] Get the source directory of a Bash script from within the script itself

  • 2008-09-12 20:39:56
  • Jiaaro
  • 1555008 View
  • 4614 Score
  • 63 Answer
  • Tags:   bash directory

33 Answered Questions

[SOLVED] How do I split a string on a delimiter in Bash?

30 Answered Questions

[SOLVED] How to concatenate string variables in Bash

19 Answered Questions

[SOLVED] How do I tell if a regular file does not exist in Bash?

  • 2009-03-12 14:48:43
  • Bill the Lizard
  • 2392629 View
  • 3041 Score
  • 19 Answer
  • Tags:   bash file-io scripting

34 Answered Questions

[SOLVED] How to check if a program exists from a Bash script?

  • 2009-02-26 21:52:49
  • gregh
  • 605025 View
  • 2006 Score
  • 34 Answer
  • Tags:   bash

9 Answered Questions

[SOLVED] Check existence of input argument in a Bash shell script

  • 2011-06-26 05:49:21
  • user775187
  • 1107602 View
  • 1190 Score
  • 9 Answer
  • Tags:   bash shell

15 Answered Questions

[SOLVED] In the shell, what does " 2>&1 " mean?

  • 2009-05-03 22:57:00
  • Tristan Havelick
  • 1017608 View
  • 2097 Score
  • 15 Answer
  • Tags:   bash shell unix redirect

Sponsored Content