1

I was testing some string manipulation stuff in a bash script and I've quickly realized it doesn't understand regular expressions (at least not with the syntax I'm using for string operations), then I've tried some glob expressions and it seems to understand some of them, some not. To be specific:

FINAL_STRING=${FINAL_STRING//<title>/$(get_title)}

is the main operation I'm trying to use and the above line works, replacing all occurrences of <title> with $(get_title) on $FINAL_STRING... and

local field=${1/#*:::/}

works, assigning $1 with everything from the beginning to the first occurrence of ::: replaced by nothing (removed). However # do what I'd expect ^ to do. Plus when I've tried to use the {,,} glob expression here:

FINAL_STRING=${FINAL_STRING//{<suffix>,<extension>}/${SUFFIX}}

to replace any occurrence of <suffix> OR <extension> by ${SUFFIX} , it works not.

So I see it doesn't take regex and it also doesn't take glob patterns... so what Does it take? Are there any exhaustive listing of what symbols/expressions are understood by plain bash string operations (particularly substring replacement)? Or are *, ?, #, ##, % and %% the only valid stuff?

(I'm trying to rely only on plain bash, without calling sed or grep to do what I want)

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
Pedro V. G.
  • 353
  • 1
  • 4
  • 13
  • A good StackOverflow question is limited in scope -- asking for a completely exhaustive list of a sublanguage is broad enough to be eligible to be closed for that reason. That said, if you *want* an extended discussion of native string operations in bash, BashFAQ #100 provides such: http://mywiki.wooledge.org/BashFAQ/100 – Charles Duffy Dec 31 '15 at 22:41
  • The bash-hackers page on parameter expansion is also an excellent reference: http://wiki.bash-hackers.org/syntax/pe – Charles Duffy Dec 31 '15 at 22:42
  • As for using a brace expansion inside a PE, I don't know why you'd expect that to work in the first place. Brace expansions **create multiple words**; a parameter expansion that parses as multiple words isn't permissible at all. – Charles Duffy Dec 31 '15 at 22:43
  • @CharlesDuffy Yeah... I was just testing possibilities. Now I'm using `extglob` option on (`shopt -s extglob`) and replaced `{a,b,c}` by `@(a|b|c)`... Very useful, since, according to that question http://stackoverflow.com/questions/17191622/why-would-i-not-leave-extglob-enabled-in-bash, there's no reason to leave `extglob` off – Pedro V. G. Dec 31 '15 at 23:55

2 Answers2

2

The gory details can be found in the bash manual, Shell Expansions section. The complete picture is surprisingly complex.

What you're doing is described in the Shell Parameter Expansion section. You'll see that the pattern in

${parameter/pattern/string}

uses the Filename Expansion rules, and those don't include Brace Expansion - that is done earlier when processing the command line arguments. Filename expansion "only" does ?, * and [...] matching (unless extglob is set).

But parameter expansion does a bit more than just filename expansion, notably the anchoring you noticed with # or %.

Mat
  • 202,337
  • 40
  • 393
  • 406
  • Now, with `extglob` turned on, this line `INPUT_INFO=${INPUT_INFO// +( ):+( )/:::}` freezes the execution... Any ideas on why? – Pedro V. G. Dec 26 '15 at 19:40
  • 1
    Can't see anything obviously wrong with that. Please post a new question with enough info to reproduce your problem (including your actual input and what you're trying to achieve). – Mat Dec 26 '15 at 19:54
1

bash does in fact handle regex; specifically, the [[ =~ ]] operator, which you can then assign to a variable using the magic variable $BASH_REMATCH. It's funky, but it works.

See: http://www.linuxjournal.com/content/bash-regular-expressions

Note this is a bash-only hack feature.

For code that works in shells besides bash as well, the old school way of doing something like this is indeed to use #/##/%/%% along with a loop around a case statement (which supports basic * glob matching).

Geoff Nixon
  • 4,697
  • 2
  • 28
  • 34