# Bash string replace

**URL:** <https://community.unix.com/t/bash-string-replace/253696>\
**Category:** Shell Programming and Scripting\
**Created:** [November 15, 2009, 1:19pm UTC](https://community.unix.com/t/bash-string-replace/253696 "2009-11-15T13:19:07Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![limmer](https://community.unix.com/letter_avatar/limmer/32/6_22734026db12803ebb3e059622ac3534.png) [@limmer](https://community.unix.com/u/limmer)\
**Post date:** [November 15, 2009, 1:19pm UTC](https://community.unix.com/t/bash-string-replace/253696/1 "2009-11-15T13:19:07Z")

</div>

Bash shell. I'm trying to filter a string taken from user input. I can replace one word at a time. This method supports regex, so is it possible to replace various words at a time?

```nohighlight
STRING="Hello World! word1 word2";

FILTERED=${STRING/word1|word2/}; # Not working: replace 2 or more words ???

echo $FILTERED;

```

---

<div class="post-metadata">

**Author:** ![Scrutinizer](https://community.unix.com/user_avatar/community.unix.com/scrutinizer/32/1216_2.png) [@Scrutinizer](https://community.unix.com/u/Scrutinizer)\
**Post date:** [November 15, 2009, 2:02pm UTC](https://community.unix.com/t/bash-string-replace/253696/2 "2009-11-15T14:02:45Z")

</div>

Parameter expansion uses shell pattern matching, not regex.  
You could use e.g. to filter out either or both words and the space before it.

```nohighlight
FILTERED=${STRING//@( word1| word2)/}

```

You need to use a double slash otherwise it will just match one word in case there are two matching words.

or, if you do not seek to filter out these specific words, just plain:

```nohighlight
FILTERED=${STRING% * *}

```

---

<div class="post-metadata">

**Author:** ![limmer](https://community.unix.com/letter_avatar/limmer/32/6_22734026db12803ebb3e059622ac3534.png) [@limmer](https://community.unix.com/u/limmer)\
**Post date:** [November 15, 2009, 3:17pm UTC](https://community.unix.com/t/bash-string-replace/253696/3 "2009-11-15T15:17:56Z")

</div>

I tried this code but is not functional (at least in bash). FILTERED still outputs the string unchanged. The second code posted does work though.

FILTERED=${STRING//@( word1| word2)/}

---

<div class="post-metadata">

**Author:** ![Scrutinizer](https://community.unix.com/user_avatar/community.unix.com/scrutinizer/32/1216_2.png) [@Scrutinizer](https://community.unix.com/u/Scrutinizer)\
**Post date:** [November 15, 2009, 3:55pm UTC](https://community.unix.com/t/bash-string-replace/253696/4 "2009-11-15T15:55:23Z")

</div>

Does this work?

bash code:

```nohighlight
shopt -s extglob
STRING="Hello World! word1 word2"
FILTERED=${STRING//@( word1| word2)/}
echo $FILTERED

```

---------- Post updated at 12:55 PM ---------- Previous update was at 12:28 PM ----------

This should work too:

```nohighlight
FILTERED=${STRING/+( word1| word2)}

```

---

<div class="post-metadata">

**Author:** ![limmer](https://community.unix.com/letter_avatar/limmer/32/6_22734026db12803ebb3e059622ac3534.png) [@limmer](https://community.unix.com/u/limmer)\
**Post date:** [November 15, 2009, 4:41pm UTC](https://community.unix.com/t/bash-string-replace/253696/5 "2009-11-15T16:41:03Z")

</div>

Yes, shopt was missing. :b:

---

<div class="post-metadata">

**Author:** ![X-Or](https://community.unix.com/letter_avatar/x-or/32/6_22734026db12803ebb3e059622ac3534.png) [@X-Or](https://community.unix.com/u/X-Or)\
**Post date:** [November 22, 2009, 9:23am UTC](https://community.unix.com/t/bash-string-replace/253696/6 "2009-11-22T09:23:41Z")

</div>

> [@scrutinizer](#):
>
> This should work too:
> 
> ```plaintext
> FILTERED=${STRING/+( word1| word2)}
> 
> ```

Bonjour,

Comment se nomme ce type de filtre ? es-ce les expressions r�guli�res ?

---

<div class="post-metadata">

**Author:** ![Scrutinizer](https://community.unix.com/user_avatar/community.unix.com/scrutinizer/32/1216_2.png) [@Scrutinizer](https://community.unix.com/u/Scrutinizer)\
**Post date:** [November 22, 2009, 9:31am UTC](https://community.unix.com/t/bash-string-replace/253696/7 "2009-11-22T09:31:55Z")

</div>

It is called extended shell pattern matching, also called extended globbing. These are not regular expressions.

---

<div class="post-metadata">

**Author:** ![danmero](https://community.unix.com/letter_avatar/danmero/32/6_22734026db12803ebb3e059622ac3534.png) [@danmero](https://community.unix.com/u/danmero)\
**Post date:** [November 22, 2009, 10:03am UTC](https://community.unix.com/t/bash-string-replace/253696/8 "2009-11-22T10:03:02Z")

</div>

```nohighlight
# STRING="Hello World! word1 word2 AND another word3 at the END.";
# FILTERED=${STRING// word[1-9]/};
# echo "$FILTERED"
Hello World! AND another at the END.

```

Works on bash

---

<div class="post-metadata">

**Author:** ![X-Or](https://community.unix.com/letter_avatar/x-or/32/6_22734026db12803ebb3e059622ac3534.png) [@X-Or](https://community.unix.com/u/X-Or)\
**Post date:** [November 22, 2009, 10:44am UTC](https://community.unix.com/t/bash-string-replace/253696/9 "2009-11-22T10:44:42Z")

</div>

Ok thanks.

```nohighlight
str="It's cold, very cold"
pattern=${str/cold/hot}
echo $pattern

```

Is possible to replace the second "cold" by "hot" and keep the first "cold" with extended globbing ?

---

<div class="post-metadata">

**Author:** ![Scrutinizer](https://community.unix.com/user_avatar/community.unix.com/scrutinizer/32/1216_2.png) [@Scrutinizer](https://community.unix.com/u/Scrutinizer)\
**Post date:** [November 23, 2009, 12:34am UTC](https://community.unix.com/t/bash-string-replace/253696/10 "2009-11-23T00:34:35Z")

</div>

```nohighlight
echo ${str%cold}hot

```

But I suspect that does not satisfy your question 😉

---

<div class="post-metadata">

**Author:** ![X-Or](https://community.unix.com/letter_avatar/x-or/32/6_22734026db12803ebb3e059622ac3534.png) [@X-Or](https://community.unix.com/u/X-Or)\
**Post date:** [November 23, 2009, 10:02am UTC](https://community.unix.com/t/bash-string-replace/253696/11 "2009-11-23T10:02:07Z")

</div>

> [@scrutinizer](#):
>
> ```plaintext
> echo ${str%cold}hot
> 
> ```
> 
> But I suspect that does not satisfy your question 😉

It do, thanks.  
The % char is used to read from the end of str ?
