30

A simple question, but I can't find the answer. the zsh documentation overwhelms me :-(

function z ()
{
  echo ${1:s/the/THE}
}

$ z thethethe
THEthethe

...

How can I get all 'the' to be replaced with 'THE', not just the first occurrence? With zsh it's the easiest things that seem to be the hardest to find examples for.

6 Answers 6

41

This is a history expansion modifier, so add the g modifier immediately before s.

print -r -- ${1:gs/the/THE}

Alternatively, use the parameter expansion syntax where a double slash means a global substitution. In this case, the part after // is a wildcard pattern, whereas history expansion substitution takes a literal string (unless the histsubstpattern option is enabled).

print -r -- ${1//the/THE}
2
  • Is it possible to write the syntax twice to apply two replacements in one line?
    – Niing
    Mar 18, 2023 at 9:02
  • 2
    @Niing In zsh, yes, you can write things like ${${var//up/down}//left/right} which replaces all occurrences of up by down and all occurrences of left by right. Mar 18, 2023 at 9:32
11

This should do the job:

VARIABLE=thethethe
print -r -- ${VARIABLE//the/THE}
THETHETHE
1
  • I am not seeing a difference with and without the double dash in second position. What is the need for this? Apr 27, 2023 at 13:41
5

Thereyago, it had to be simple:

print -r -- ${1//the/THE}

... the double slash does it, and you can't fool around with " :s "

BTW, I'd sure like to thank the 'StackExchange' sites for existing. Of all the zillions of places one might ask a question, these are by far the best--one not only almost always gets answers, but those answers are invariably of the highest quality.

4

There are many answers, but none of them are comprehensive, so I felt like adding an answer that sums it all up.

Lower/Uppercasing

If you are trying to uppercase the string, the simplest way is to use:

> str="thethethe"
> upper="$str:u"
> echo $upper
THETHETHE

(Not part of the original question, but just in case) If you are trying to lowercase, the same goes for :l.

Replacing substrings

If you want to replace a single occurrence, use this:

> str="thethethe"
> echo ${str/the/man}
manthethe

If you add an extra slash between the variable and the test to substitute, it will replace all the occurrences:

> str="thethethe"
> echo ${str//the/man}
manmanman

Another option is to use the history modifiers, just like Gilles suggested:

> str="thethethe"
> echo ${str:gs/the/man}
manmanman
1

// works perfect if you're only trying to replace a specific word to all caps while leaving the rest of it untouched. If you are trying to convert everything to uppercase, you can use ":u" on the variable

SOME_ENV_VALUE='thethethe'
print -r -- $SOME_ENV_VALUE:u # outputs: THETHETHE

You can verify which modifiers you have available in the zsh expansion and substitution manual

man zshexpn

Or with

info zsh modifiers 

If you have the info pages installed.

0

Just want to help people and myself, since I just recovered from some accidental deletion:

readonly question="${@:2}"
question_json="${question//$'\n'/\\\n}"    # replace newline with: \n
question_json="${question_json//\"/\\\"}"  # replace double-quote with: \"
4
  • In zsh, which is the shell discussed in this Q&A, that replaces newlines with \\n, not \n. That ${@:2} is more ksh93 syntax. In zsh, you'd use $@[3,-1] or $argv[3,-1] (though it now supports the ksh93 syntax as well for compatibility with that shell). In zsh, that will join the elements with the first character of $IFS. If you wanted $question to have the 3rd to last positional parameters joined with a space character and with newlines replaced with \n and " with \", you'd do: question_json=${${(j[ ])argv[3,-1]//$'\n'/\\n}/\"/\\\"}. Mar 28, 2023 at 6:40
  • To do proper JSON encoding, you'd use something like jq: question_json=$(jq -n --arg a "${(j[ ])argv[3,-1]}" '$a') (here assuming positional parameters contain properly UTF-8 encoded text and no NUL characters). Mar 28, 2023 at 6:41
  • What is JSON anyway? Mar 30, 2023 at 1:48
  • 1
    @RayAndrews I'm not sure whether or not you already have an answer in mind because it's very much a common sense, but anyway I meant en.wikipedia.org/wiki/JSON. I was building an app for ChatGPT and they require the data format to be written in JSON.
    – Niing
    Mar 30, 2023 at 16:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .