bhylu.com

Advertisements

Bash sed

Transform a stream and preserve the original source.

How it works

sed applies editing commands to a stream of lines. A substitution changes matching text in the output; without an explicit in-place option the original file remains untouched. That default is useful when reviewing changes before replacement. Regex syntax, escaping and replacement metacharacters have their own rules, separate from shell quoting.

Run the code

Reviewed with Git for Windows Bash 5.2.37. Open Git Bash, save the download with LF line endings in a separate learning folder, check it with bash -n lesson-name.sh, then run bash lesson-name.sh using the actual filename. Bash 4 or newer is required for the full course. Linux-only notes identify unavailable tools or POSIX behaviour. There is no Bash browser runner; Apache and MySQL are not required.

This complete example was executed in the stated local review environment.

The complete source creates a fresh private temporary workspace and checks its physical path before cleanup. All file fixtures belong to that workspace; do not remove the guards or point it at existing documents.

Download complete source

Example

sed.sh

#!/usr/bin/env bash
set -u
set -o pipefail
export LC_ALL=C

# Own a new directory; verify physical paths before cleanup.
parent=$(cd -- "${TMPDIR:-/tmp}" && pwd -P) || exit 1
work=$(mktemp -d "$parent/bhylu-bash.XXXXXX") || exit 1
work=$(cd -- "$work" && pwd -P) || exit 1
case "$work" in "$parent"/bhylu-bash.??????) ;; *) exit 1 ;; esac
cleanup() {
    cd -- "$parent" || return 1
    [[ -d $work && ! -L $work ]] || return 1
    [[ $(cd -- "$work" && pwd -P) == "$work" ]] || return 1
    case "$work" in "$parent"/bhylu-bash.??????) rm -r -- "$work" ;; *) return 1 ;; esac
}
trap cleanup EXIT
cd -- "$work" || exit 1

printf "state=draft\nstate=ready\n" > states.txt
sed 's/^state=draft$/state=review/' states.txt > reviewed.txt
[[ $(head -n 1 states.txt) == "state=draft" ]] || exit 1
cat -- reviewed.txt

Focus on the lesson commands

This excerpt omits temporary-workspace setup and cleanup. Use the complete source above to run the example.

Command excerpt

printf "state=draft\nstate=ready\n" > states.txt
sed 's/^state=draft$/state=review/' states.txt > reviewed.txt
[[ $(head -n 1 states.txt) == "state=draft" ]] || exit 1
cat -- reviewed.txt

Expected result

state=review
state=ready

The anchors limit the transformation to an entire expected line, and the result goes to a new file. The source assertion confirms the original is unchanged. GNU and BSD sed differ in some options, particularly in-place editing, so prefer an explicitly reviewed output path when portability matters.

Primary technical reference: Bash documentation.