sed can rewrite matching text as it passes through a stream. Replacement text can come from a variable.

Program

Play the script to replace a status word with a selected output value.

replacement
sed_replace.sh
Replay: real traced execution (multi-file project)
#!/usr/bin/env bash

line="task:todo"
replacement="done"
updated="$(printf '%s\n' "$line" | sed "s/todo/$replacement/")"
echo "$updated"
#!/usr/bin/env bash

line="task:todo"
replacement="ready"
updated="$(printf '%s\n' "$line" | sed "s/todo/$replacement/")"
echo "$updated"
#!/usr/bin/env bash

line="task:todo"
replacement="blocked"
updated="$(printf '%s\n' "$line" | sed "s/todo/$replacement/")"
echo "$updated"
  1. line ← task:todo

    3line="task:todo"4replacement="done"
    values this steptask:todoline
  2. replacement ← done

    3line="task:todo"4replacement="done"5updated="$(printf '%s\n' "$line" | sed "s/todo/$replacement/")"
    values this stepdonereplacement
  3. updated ← task:done

    4replacement="done"5updated="$(printf '%s\n' "$line" | sed "s/todo/$replacement/")"6echo "$updated"
    values this steptask:doneupdateddonereplacement
  4. echo "$updated"

    5updated="$(printf '%s\n' "$line" | sed "s/todo/$replacement/")"6echo "$updated"
    outputtask:done
    values this steptask:doneupdated
  1. line ← task:todo

    3line="task:todo"4replacement="ready"
    values this steptask:todoline
  2. replacement ← ready

    3line="task:todo"4replacement="ready"5updated="$(printf '%s\n' "$line" | sed "s/todo/$replacement/")"
    values this stepreadyreplacement
  3. updated ← task:ready

    4replacement="ready"5updated="$(printf '%s\n' "$line" | sed "s/todo/$replacement/")"6echo "$updated"
    values this steptask:readyupdatedreadyreplacement
  4. echo "$updated"

    5updated="$(printf '%s\n' "$line" | sed "s/todo/$replacement/")"6echo "$updated"
    outputtask:ready
    values this steptask:readyupdated
  1. line ← task:todo

    3line="task:todo"4replacement="blocked"
    values this steptask:todoline
  2. replacement ← blocked

    3line="task:todo"4replacement="blocked"5updated="$(printf '%s\n' "$line" | sed "s/todo/$replacement/")"
    values this stepblockedreplacement
  3. updated ← task:blocked

    4replacement="blocked"5updated="$(printf '%s\n' "$line" | sed "s/todo/$replacement/")"6echo "$updated"
    values this steptask:blockedupdatedblockedreplacement
  4. echo "$updated"

    5updated="$(printf '%s\n' "$line" | sed "s/todo/$replacement/")"6echo "$updated"
    outputtask:blocked
    values this steptask:blockedupdated

Follow the Replacement

  1. line starts as task:todo.
  2. replacement starts as done.
  3. sed "s/todo/$replacement/" replaces todo with done.
  4. updated becomes task:done.
  5. The script prints task:done. | replacement | updated text | | --- | --- | | done | task:done | | ready | task:ready | | blocked | task:blocked |
sed substitute `s/old/new/` replaces the first matching text on each input line.
double quotes Double quotes around the sed script allow `$replacement` to expand.
stream rewrite The original variable stays the same; the rewritten text is captured separately.

Exercise: sed_replace.sh

Reproduce task:done, then change replacement to the pinned variants ready and blocked and predict task:ready and task:blocked.