Skip to content

Sed Quick Guide

Sed, an acronym for Stream EDitor, is a powerful and versatile command-line utility for parsing and transforming text. Developed by Lee E. McMahon at Bell Labs in 1973-74, Sed has become a staple tool on virtually all Unix-like operating systems, including GNU/Linux and macOS.

McMahon designed Sed as a general-purpose, line-oriented editor, drawing inspiration and features from the earlier ed editor. A key strength of Sed, present since its inception, is its support for regular expressions, allowing for sophisticated pattern matching and text manipulation. Sed processes input from files, pipes, or standard input streams, making it highly flexible for various text processing tasks.

The version commonly found on GNU/Linux systems is GNU Sed, maintained as part of the GNU Project. While Sed’s syntax might seem cryptic to newcomers, mastering it unlocks the ability to solve complex text manipulation problems with concise scripts. This efficiency is a hallmark of Sed’s design.

Sed is commonly used for a wide range of tasks, including:

  • Text substitution (find and replace).
  • Selective printing of lines from a file.
  • In-place editing of files (modifying files directly).
  • Non-interactive batch editing of text.
  • Filtering and transforming text in pipelines.
  • Data cleaning and reformatting (e.g., CSV or log files).

This section describes how to ensure Sed is available and, if necessary, how to install or update it on a GNU/Linux system.

Sed is typically pre-installed on most GNU/Linux distributions and macOS. You can check if it’s available and find its version by running:

[user]$ sed --version

Output might look like (version numbers and details will vary):

sed (GNU sed) 4.8
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by Jay Fenlason, Tom Lord, Ken Pizzini,
and Paolo Bonzini.
GNU sed home page: <https://www.gnu.org/software/sed/>.
General help using GNU software: <https://www.gnu.org/gethelp/>.
E-mail bug reports to: <bug-sed@gnu.org>.

If the command is not found, or if you need a specific version (e.g., GNU Sed on macOS, which defaults to BSD Sed), you may need to install it.

On Debian-based systems (like Ubuntu, Mint):

[user]$ sudo apt update
[user]$ sudo apt install sed

On RPM-based systems (like Fedora, CentOS, RHEL): Older systems use yum, newer ones use dnf.

# For DNF-based systems (e.g., Fedora, RHEL 8+)
[root]# dnf install sed
# For YUM-based systems (e.g., CentOS 7)
[root]# yum install sed

On macOS (to get GNU Sed, as BSD Sed is default): Using Homebrew is recommended.

[user]$ brew install gnu-sed

After installation via Homebrew, GNU Sed is typically available as gsed. You might need to add it to your PATH or use gsed explicitly.

Installing from source is rarely necessary for a utility like Sed but is an option for advanced users or specific needs. Always download source code from official GNU mirrors.

General steps:

  1. Download the latest source tarball (e.g., sed-latest.tar.gz or sed-latest.tar.xz) from a GNU FTP server (e.g., https://ftp.gnu.org/gnu/sed/). [user]$ wget https://ftp.gnu.org/gnu/sed/sed-latest.tar.xz (Replace with actual latest version link)
  2. Extract the archive: [user]$ tar xvf sed-latest.tar.xz
  3. Navigate into the extracted directory: [user]$ cd sed-*/ (The directory name will match the version)
  4. Configure the build: [user]$ ./configure
  5. Compile the source code: [user]$ make
  6. Run tests (optional but recommended): [user]$ make check
  7. Install the compiled utility (requires superuser privileges): [user]$ sudo make install

After these steps, verify the installation with sed --version.

Understanding Sed’s internal workflow is key to using it effectively. Sed processes text in a cyclical manner for each input line. The core components involved are the pattern space and the hold space.

The basic workflow for each line is:

  1. Read: Sed reads one line from the input stream (file, pipe, or standard input). The trailing newline character is removed internally before placing it into the pattern space, an internal buffer where editing operations occur.
  2. Execute: All Sed commands specified in the script are applied sequentially to the text in the pattern space. Commands can be restricted to specific lines using addresses.
  3. Display: After all commands have been executed for the current line in the pattern space, Sed, by default, prints the contents of the pattern space to the output stream, followed by a newline character. This default printing can be suppressed with the -n option.
  4. Repeat: Sed then clears the pattern space (unless specific commands like N modify this) and repeats the cycle with the next input line until the end of the input is reached.
  • Pattern Space: A temporary, in-memory buffer where the current input line is held and manipulated by Sed commands. Its contents are typically cleared and refilled for each new input line.
  • Hold Space: Another temporary, in-memory buffer. Unlike the pattern space, the hold space is not automatically cleared between cycles. Data can be copied from the pattern space to the hold space (e.g., with h or H) and from the hold space to the pattern space (e.g., with g or G). This allows for more complex, multi-line operations and data preservation across lines. Sed commands do not operate directly on the hold space; data must be moved to the pattern space first.
  • Input File Unchanged: By default, Sed does not modify the original input file. It sends its output to standard output. To modify a file in-place, GNU Sed offers the -i option.
  • Global Application: If no line addressing is specified for a command, it applies to all lines in the input.
  • Standard Input (stdin): If no input files are given, Sed reads from stdin.

Let’s create a file quote.txt: `There is only one thing that makes a dream impossible to achieve: the fear of failure.

  • Paulo Coelho, The Alchemist`

Command: sed 's/dream/goal/' quote.txt

  • Cycle 1:
    1. Read: Sed reads “There is only one thing that makes a dream impossible to achieve: the fear of failure.” into the pattern space.
    1. Execute: The command s/dream/goal/ is applied. “dream” is found and replaced with “goal”. Pattern space now: “There is only one thing that makes a goal impossible to achieve: the fear of failure.”
    1. Display: Sed prints the content of the pattern space to standard output.
  • Cycle 2:
    1. Read: Sed reads ”- Paulo Coelho, The Alchemist” into the pattern space.
    1. Execute: The command s/dream/goal/ is applied. “dream” is not found. Pattern space remains unchanged.
    1. Display: Sed prints the content of the pattern space to standard output.

Output of the command:

There is only one thing that makes a goal impossible to achieve: the fear of failure.
- Paulo Coelho, The Alchemist

Sed - Basic Syntax (Reiteration for Quick Guide)

Section titled “Sed - Basic Syntax (Reiteration for Quick Guide)”

As covered earlier, Sed’s basic invocation forms are:

sed [options] 'command(s)' [file(s)]
sed [options] -f scriptfile [file(s)]

Key options include -n (suppress default output), -e (specify a script), and -f (specify a script file). GNU Sed offers -r (or -E) for extended regex and -i for in-place editing.

Example with books.txt (see ‘Basic Syntax and Options’ chapter for books.txt content): Delete lines 1, 2, and 5.

[user]$ sed -e '1d' -e '2d' -e '5d' books.txt

Output:

3) The Alchemist, Paulo Coelho, 197
4) The Fellowship of the Ring, J. R. R. Tolkien, 432
6) A Game of Thrones, George R. R. Martin, 864

Sed provides commands for basic looping and conditional branching, allowing for more complex script logic, similar to goto statements in other languages.

A label is a marker in your Sed script that you can jump to. Define a label using a colon followed by the label name:

:mylabel
:start_loop
:process_data

The b command branches (jumps) to a specified label. If no label is given, it branches to the end of the script, effectively starting the next cycle with a new input line.

Syntax: [address]b [label]

Example: Process books.txt (assuming titles and authors on alternating lines as in the ‘Managing Patterns’ chapter examples for this section). Combine title and author, then prepend ”- ” to lines containing “Paulo”.

Sample books_alternate.txt for this section: A Storm of Swords George R. R. Martin The Two Towers J. R. R. Tolkien The Alchemist Paulo Coelho The Fellowship of the Ring J. R. R. Tolkien The Pilgrimage Paulo Coelho A Game of Thrones George R. R. Martin

[user]$ sed -n 'N; s/\n/, /; /Paulo/!b Print; s/^/- /; :Print; p' books_alternate.txt

Explanation:

  1. N: Appends the next line to the pattern space, separated by a newline.
  2. s/\n/, /: Replaces the embedded newline with ”, ”. Pattern space now: “Title, Author”.
  3. /Paulo/!b Print: If the line does not (!) contain “Paulo”, branch (b) to the label Print.
  4. s/^/- /: If the branch was not taken (i.e., line contains “Paulo”), prepend ”- ”.
  5. :Print: Defines the label Print.
  6. p: Print the pattern space.

Output:

A Storm of Swords, George R. R. Martin
The Two Towers, J. R. R. Tolkien
- The Alchemist, Paulo Coelho
The Fellowship of the Ring, J. R. R. Tolkien
- The Pilgrimage, Paulo Coelho
A Game of Thrones, George R. R. Martin

The commands can be written on separate lines in a script file for better readability, or separated by semicolons (though N, labels, and branching often work best with newlines).

The t command provides conditional branching: it jumps to a label only if a s/// (substitute) command has made a successful substitution since the last input line was read or the last t command was executed.

Syntax: [address]t [label]

Example: Using books_alternate.txt (title/author on alternating lines), prepend up to four hyphens to lines mentioning “Paulo”.

[user]$ sed -n 'N; s/\n/, /; :Loop; /Paulo/s/^/-/;/----/!t Loop; p' books_alternate.txt

Explanation:

  1. N; s/\n/, /: Combine title and author as before.
  2. :Loop: Define a label Loop.
  3. /Paulo/s/^/-: If line contains “Paulo”, prepend one hyphen. This is the s/// command that t will test.
  4. /----/!t Loop: If the line does not yet start with four hyphens, and if the previous s/^/-/ command made a substitution, then branch (t) back to Loop.
  5. p: Print the pattern space.

Output:

A Storm of Swords, George R. R. Martin
The Two Towers, J. R. R. Tolkien
----The Alchemist, Paulo Coelho
The Fellowship of the Ring, J. R. R. Tolkien
----The Pilgrimage, Paulo Coelho
A Game of Thrones, George R. R. Martin

The t command is crucial for creating loops that terminate based on the success of substitutions.

Sed - Working with Pattern and Hold Spaces

Section titled “Sed - Working with Pattern and Hold Spaces”

The pattern space is where Sed performs its operations on the current line. The hold space is an auxiliary buffer for storing data across line processing cycles. Understanding how to move data between these spaces is key to advanced Sed scripting.

Let’s use books.txt (original format: ID) Title, Author, Pages) for these examples unless specified.

p: Prints the entire current content of the pattern space. P (uppercase): Prints the portion of the pattern space up to the first embedded newline (\n). Useful with multi-line commands like N.

Example: Print only the 3rd line (use -n to suppress default output).

[user]$ sed -n '3p' books.txt

Output:

3) The Alchemist, Paulo Coelho, 197

Commands can be restricted to specific lines or ranges:

  • N: Line number N (e.g., 3p prints line 3).
  • N,M: Lines N through M (e.g., 2,5p prints lines 2 to 5).
  • $ : The last line of input (e.g., $p prints the last line).
  • N,$: Lines N through the last line (e.g., 3,$p prints from line 3 to end).
  • M,+n (GNU extension): Lines M and the next n lines (e.g., 2,+2p prints lines 2, 3, 4).
  • M~n (GNU extension): Every nth line starting from line M (e.g., 1~2p prints odd lines: 1, 3, 5…; 2~2p prints even lines: 2, 4, 6…).
  • /pattern/: Lines matching the regular expression pattern.

Example: Print odd lines from books.txt.

[user]$ sed -n '1~2p' books.txt

Output:

1) A Storm of Swords, George R. R. Martin, 1216
3) The Alchemist, Paulo Coelho, 197
5) The Pilgrimage, Paulo Coelho, 288

Commands can also be addressed by patterns:

  • /pattern/command: Execute command on lines matching pattern.
  • /pattern1/,/pattern2/command: Execute command on lines from the first match of pattern1 to the first subsequent match of pattern2 (inclusive).
  • /pattern/,Np: From line matching pattern to line number N.

Example: Print all books by “Paulo Coelho”.

[user]$ sed -n '/Paulo Coelho/p' books.txt

Output:

3) The Alchemist, Paulo Coelho, 197
5) The Pilgrimage, Paulo Coelho, 288

Example: Print lines from the first occurrence of “Two Towers” to “Pilgrimage”.

[user]$ sed -n '/Two Towers/,/Pilgrimage/p' books.txt

Output:

2) The Two Towers, J. R. R. Tolkien, 352
3) The Alchemist, Paulo Coelho, 197
4) The Fellowship of the Ring, J. R. R. Tolkien, 432
5) The Pilgrimage, Paulo Coelho, 288

Using books_alternate.txt (title on one line, author on the next) for these examples:

  • h: Copy pattern space to hold space (overwrites hold space).
  • H: Append pattern space to hold space (adds a newline then the pattern space content).
  • g: Copy hold space to pattern space (overwrites pattern space).
  • G: Append hold space to pattern space (adds a newline then the hold space content).
  • x: Exchange contents of pattern space and hold space.
  • n: Print current pattern space (if not suppressed by -n), then read next line into pattern space.
  • N: Append next line to pattern space (with a \n separator).

Example: Print only author names from books_alternate.txt.

[user]$ sed -n 'h; n; p; x; d' books_alternate.txt # More direct: sed -n 'n;p' books_alternate.txt

A simpler way to print every second line (authors):

[user]$ sed -n 'n;p' books_alternate.txt

Output (authors):

George R. R. Martin
J. R. R. Tolkien
Paulo Coelho
J. R. R. Tolkien
Paulo Coelho
George R. R. Martin

Example: Reverse order of title and author (print Author, then Title).

[user]$ sed -n 'h; n; p; g; p' books_alternate.txt

Explanation:

  1. h: Current line (Title) copied to hold space.
  2. n: Next line (Author) read into pattern space.
  3. p: Print pattern space (Author).
  4. g: Copy hold space (Title) back to pattern space.
  5. p: Print pattern space (Title).

Output:

George R. R. Martin
A Storm of Swords
J. R. R. Tolkien
The Two Towers
...

This section covers essential Sed commands for text manipulation, using books.txt (ID) Title, Author, Pages) unless specified.

[address1[,address2]]d Deletes the pattern space, so the line is not printed. A new cycle begins immediately.

Example: Delete line 4.

[user]$ sed '4d' books.txt

Output (line 4 is missing):

1) A Storm of Swords, George R. R. Martin, 1216
2) The Two Towers, J. R. R. Tolkien, 352
3) The Alchemist, Paulo Coelho, 197
5) The Pilgrimage, Paulo Coelho, 288
6) A Game of Thrones, George R. R. Martin, 864

[address1[,address2]]w filename Writes the pattern space to filename. The file is created if it doesn’t exist or overwritten if it does (truncated at the start of the Sed script).

Example: Write lines containing “Tolkien” to tolkien_books.txt.

[user]$ sed -n '/Tolkien/w tolkien_books.txt' books.txt # Use -n if only writing, not printing
[user]$ cat tolkien_books.txt

Output from cat tolkien_books.txt:

2) The Two Towers, J. R. R. Tolkien, 352
4) The Fellowship of the Ring, J. R. R. Tolkien, 432

[address]a\ text to append Appends text to append after the current line. The text must be preceded by a backslash if on the same line as a, or start on the next line.

Example: Append text after line 2.

[user]$ sed '2a\
---> Inserted Line <---' books.txt

Output:

1) A Storm of Swords, George R. R. Martin, 1216
2) The Two Towers, J. R. R. Tolkien, 352
---> Inserted Line <---
3) The Alchemist, Paulo Coelho, 197
...

[address]i\ text to insert Inserts text to insert before the current line. Syntax for text is similar to a.

Example: Insert text before line 1.

[user]$ sed '1i\
*** START OF FILE ***' books.txt

Output:

*** START OF FILE ***
1) A Storm of Swords, George R. R. Martin, 1216
2) The Two Towers, J. R. R. Tolkien, 352
...

[address1[,address2]]c\ new text Replaces the line(s) matching the address range with new text. If a range is given, all lines in that range are replaced by a single instance of new text.

Example: Change line 3.

[user]$ sed '3c\
REPLACED: This was line 3.' books.txt

Output:

1) A Storm of Swords, George R. R. Martin, 1216
2) The Two Towers, J. R. R. Tolkien, 352
REPLACED: This was line 3.
4) The Fellowship of the Ring, J. R. R. Tolkien, 432
...

[address1[,address2]]y/source-chars/dest-chars/ Translates characters. Each character in source-chars is replaced by the character at the corresponding position in dest-chars. source-chars and dest-chars must be the same length. Regular expressions are not used here.

Example: Convert lowercase ‘aeio’ to uppercase ‘AEIO’ on lines containing “Alchemist”.

[user]$ sed '/Alchemist/y/aeio/AEIO/' books.txt

Output (line 3 is modified):

1) A Storm of Swords, George R. R. Martin, 1216
2) The Two Towers, J. R. R. Tolkien, 352
3) ThE AlchEmIst, PAUlO COElhO, 197
4) The Fellowship of the Ring, J. R. R. Tolkien, 432
...

[address1[,address2]]l [length] (length is GNU extension) Prints the pattern space in an unambiguous form: non-printable characters are shown as escape sequences (e.g., tab as \t), and long lines are wrapped. GNU Sed allows specifying wrap length.

Example: Display books.txt with a wrap length of 30.

[user]$ sed -n 'l 30' books.txt

Output (example for first line):

1) A Storm of Swords, George \
R. R. Martin, 1216$

[address]q [exit-code] (exit-code is GNU extension) Sed immediately stops processing and exits. If address is given, quit occurs when that line is reached. GNU Sed allows specifying an exit-code.

Example: Print the first 3 lines (like head -3).

[user]$ sed '3q' books.txt

Output:

1) A Storm of Swords, George R. R. Martin, 1216
2) The Two Towers, J. R. R. Tolkien, 352
3) The Alchemist, Paulo Coelho, 197

[address]r filename Reads the content of filename and appends it to the output after the line matching address is processed (or at end of script if no address). If address is 0 (GNU Sed), reads at the beginning.

[user]$ echo "--- Additional Content ---" > extra.txt
[user]$ sed '3r extra.txt' books.txt

Output (content of extra.txt inserted after line 3):

1) A Storm of Swords, George R. R. Martin, 1216
2) The Two Towers, J. R. R. Tolkien, 352
3) The Alchemist, Paulo Coelho, 197
--- Additional Content ---
4) The Fellowship of the Ring, J. R. R. Tolkien, 432
...

[address1[,address2]]e [command] Executes command. The output of command is sent to standard output. If command is omitted, the content of the pattern space is executed as a command. This is a powerful but potentially dangerous GNU Sed extension.

Example: Run date command after line 1.

[user]$ sed '1e date' books.txt

Output (date output appears after line 1, original line 1 is also printed):

1) A Storm of Swords, George R. R. Martin, 1216
Wed Mar 27 10:30:00 EDT 2024 (Actual date will vary)
2) The Two Towers, J. R. R. Tolkien, 352
...

Sed treats a couple of special characters as commands themselves, offering unique functionalities.

[address1[,address2]]= Prints the current input line number to standard output, followed by a newline.

Example: Print line numbers before each line.

[user]$ sed '=' books.txt

Output:

1
1) A Storm of Swords, George R. R. Martin, 1216
2
2) The Two Towers, J. R. R. Tolkien, 352
...

Example: Count lines in a file (like wc -l).

[user]$ sed -n '$=' books.txt

Output (total number of lines):

6

If the first character of a Sed command is #, the entire line is treated as a comment and ignored by Sed (unless it’s #n, which is equivalent to the -n option if it’s the very first line of the script). Comments are useful for annotating Sed scripts.

Example in a script file comment_example.sed:

# This is a comment, it will be ignored.
# Print lines containing 'Tolkien'
/Tolkien/p
[user]$ sed -n -f comment_example.sed books.txt

Output (only Tolkien books):

2) The Two Towers, J. R. R. Tolkien, 352
4) The Fellowship of the Ring, J. R. R. Tolkien, 432

While not a command itself, the ampersand & has a special meaning in the replacement part of a substitute command (s/pattern/replacement/). It stands for the entire text matched by pattern.

Example: Enclose all occurrences of “George R. R. Martin” in asterisks.

[user]$ sed 's/George R. R. Martin/**&**/g' books.txt

Output:

1) A Storm of Swords, **George R. R. Martin**, 1216
2) The Two Towers, J. R. R. Tolkien, 352
...
6) A Game of Thrones, **George R. R. Martin**, 864

Sed - String Manipulation (Reiteration for Quick Guide)

Section titled “Sed - String Manipulation (Reiteration for Quick Guide)”

The s (substitute) command is Sed’s primary tool for string manipulation. Syntax: [address]s/pattern/replacement/[flags].

Common flags: g (global), N (Nth occurrence), p (print), w file (write), i (ignore case - GNU).

Example: Replace all commas with semicolons in books.txt.

[user]$ sed 's/,/;/g' books.txt

Output:

1) A Storm of Swords; George R. R. Martin; 1216
2) The Two Towers; J. R. R. Tolkien; 352
...

Capturing groups (\(...\) in BRE, (...) in ERE) allow reordering and reusing parts of the matched text with \1, \2, etc. in the replacement.

Example: Swap author and title (assuming format ‘Title, Author’).

[user]$ echo "The Hobbit, J. R. R. Tolkien" | sed -E 's/([^,]+), *(.+)/\2 - \1/'

Output:

J. R. R. Tolkien - The Hobbit

GNU Sed offers \L, \U, \l, \u, \E for case conversion in replacements.

Sed - Regular Expressions (Reiteration for Quick Guide)

Section titled “Sed - Regular Expressions (Reiteration for Quick Guide)”

Sed’s power comes from regular expressions. It uses Basic Regular Expressions (BRE) by default. Extended Regular Expressions (ERE) can be enabled with -E (POSIX) or -r (GNU).

Key Metacharacters (BRE examples, ERE often simpler):

  • ^: Start of line.
  • $: End of line.
  • .: Any single character (except newline).
  • [...]: Character set (e.g., [abc]).
  • [^...]: Negated character set.
  • *: Zero or more of the preceding item.
  • \?: Zero or one (BRE: \?, ERE: ?).
  • \+: One or more (BRE: \+, ERE: +).
  • \{N\}: Exactly N times (BRE: \{N\}, ERE: {N}).
  • \{N,\}: At least N times.
  • \{N,M\}: Between N and M times.
  • \(...\): Grouping for capturing (BRE: \(...\), ERE: (...)).
  • \|: Alternation OR (BRE: \| inside \(\) , ERE: |).

POSIX Character Classes: [[:alnum:]], [[:alpha:]], [[:digit:]], [[:space:]], etc. Provide portable ways to match character types.

Example: Print lines starting with a digit.

[user]$ sed -n '/^[[:digit:]]/p' books.txt

Output (all lines from books.txt as they start with digits):

1) A Storm of Swords, George R. R. Martin, 1216
2) The Two Towers, J. R. R. Tolkien, 352
3) The Alchemist, Paulo Coelho, 197
4) The Fellowship of the Ring, J. R. R. Tolkien, 432
5) The Pilgrimage, Paulo Coelho, 288
6) A Game of Thrones, George R. R. Martin, 864

GNU Sed Metacharacters: \b (word boundary), \s (whitespace), \w (word char), etc., offer Perl-like conveniences.

This section demonstrates Sed’s versatility by simulating common Unix utilities and performing practical tasks. These examples showcase various Sed commands and techniques.

Default behavior (empty script prints lines):

[user]$ sed '' books.txt

Using print command with -n:

[user]$ sed -n 'p' books.txt

The pattern ^$ matches empty lines.

[user]$ echo -e "Line #1\n\n\nLine #2" | sed '/^$/d'

Output:

Line #1
Line #2

Removing Commented Lines (e.g., from C++ // comments)

Section titled “Removing Commented Lines (e.g., from C++ // comments)”

Sample hello.cpp:

#include <iostream>
// using namespace std; // A commented out line
int main(void) {
// Displays message on stdout.
std::cout << "Hello, World !!!" << std::endl; // Another comment
return 0; /* Not this type of comment */
}
[user]$ sed 's|//.*||g' hello.cpp

Output (lines with // comments are stripped, or the comment part is removed):

#include <iostream>
int main(void) {
std::cout << "Hello, World !!!" << std::endl;
return 0; /* Not this type of comment */
}

Note: This regex is basic and might not handle all C++ comment scenarios perfectly (e.g., // inside strings). For robust parsing, dedicated tools are better.

Adding Comments Before Certain Lines (e.g., Shell script)

Section titled “Adding Comments Before Certain Lines (e.g., Shell script)”

Sample hello.sh: #!/bin/bash pwd hostname uname -a who who -r lsb_release -a

[user]$ sed '3,5s/^/# /' hello.sh

Output (lines 3 to 5 are commented out):

#!/bin/bash
pwd
# hostname
# uname -a
# who
who -r
lsb_release -a
[user]$ sed -n '$=' hello.sh

Output (number of lines in hello.sh):

7

Example: head -3 books_alternate.txt

[user]$ sed '3q' books_alternate.txt

Output:

A Storm of Swords
George R. R. Martin
The Two Towers
[user]$ sed -n '$p' books_alternate.txt

Output:

George R. R. Martin

More robust tail -N requires more complex Sed (often involving hold space and loops), or use tac file | sed Nq | tac.

DOS/Windows uses CR+LF (\r\n) for line endings. Unix uses LF (\n). ^M often represents CR.

[user]$ echo -e "Line #1\r\nLine #2\r" > test_dos.txt
[user]$ file test_dos.txt

Output from file:

test_dos.txt: ASCII text, with CRLF line terminators
[user]$ sed 's/\r$//' test_dos.txt > test_unix.txt # More portable
[user]$ file test_unix.txt

Output from file:

test_unix.txt: ASCII text

The s/\r$// command removes the carriage return (\r) if it’s at the end of the line ($).

[user]$ echo -e "Line #1\nLine #2" > test_unix2.txt
[user]$ sed 's/$/\r/' test_unix2.txt > test_dos2.txt
[user]$ file test_dos2.txt

Output from file:

test_dos2.txt: ASCII text, with CRLF line terminators

The s/$/\r/ command adds a carriage return (\r) at the end of every line ($).

Simulating cat -E (Show $ at End of Lines)

Section titled “Simulating cat -E (Show $ at End of Lines)”
[user]$ sed 's/$/$/' books.txt # Replace end-of-line with literal $

Output (example for first line):

1) A Storm of Swords, George R. R. Martin, 1216$
[user]$ echo -e "Column1\tColumn2\nValue1\tValue2" > tab_file.txt
[user]$ sed 's/\t/^I/g' tab_file.txt # Note: ^I is a literal tab character, type Ctrl-V then Tab

Alternatively, use l command (which shows \t by default) if exact ^I visualization isn’t strictly needed or pipe to tr:

[user]$ sed -n 'l' tab_file.txt # Shows tabs as \t
[user]$ sed 's/\t/TEMP_TAB/g' tab_file.txt | tr 'TEMP_TAB' '\t' | cat -T # Complex way for literal ^I
[user]$ sed '=' books.txt | sed 'N; s/\n/\t/'

Explanation:

  • sed '=' books.txt: Prints line number, then the line.
  • sed 'N; s/\n/\t/': Merges each pair of lines (number and content line) and replaces the newline between them with a tab.

Output (example for first line):

1 1) A Storm of Swords, George R. R. Martin, 1216
[user]$ sed -n 'w books_copy.txt' books.txt
[user]$ diff books.txt books_copy.txt && echo "Files are identical"

Output (if successful):

Files are identical

Simulating expand (Convert Tabs to Spaces)

Section titled “Simulating expand (Convert Tabs to Spaces)”

This example converts each tab to 4 spaces. True expand has more complex tab stop logic.

[user]$ sed 's/\t/ /g' tab_file.txt

Output:

Column1 Column2
Value1 Value2

Simulating tee (Output to Screen and File)

Section titled “Simulating tee (Output to Screen and File)”
[user]$ echo -e "Data line 1\nData line 2" | sed 'p; w output.txt'

Explanation: p prints to stdout. w output.txt writes to file. Since default printing is on, p causes double printing to stdout. Use -n for exact tee behavior.

[user]$ echo -e "Data line 1\nData line 2" | sed -n 'p; w output.txt'
[user]$ cat output.txt

Output to screen and in output.txt:

Data line 1
Data line 2

Replace multiple consecutive blank lines with a single blank line.

[user]$ echo -e "Line 1\n\n\nLine 2\n\nLine 3" > blank_lines.txt
[user]$ sed '/^$/{N;/^\n$/D;}' blank_lines.txt

Explanation for /^$/{N;/^\n$/D;}:

  • /^$/: If the line is empty…
  • N: Append the next line. Pattern space might be \n (if next line was also empty).
  • /^\n$/D: If pattern space is just \n (two consecutive empty lines), delete up to the \n and restart cycle with the remainder. This effectively removes one of the empty lines and re-evaluates the new pattern space.

Output:

Line 1
Line 2
Line 3

Simulating grep pattern (Print Matching Lines)

Section titled “Simulating grep pattern (Print Matching Lines)”
[user]$ sed -n '/Alchemist/p' books.txt

Output:

3) The Alchemist, Paulo Coelho, 197

Simulating grep -v pattern (Print Non-Matching Lines)

Section titled “Simulating grep -v pattern (Print Non-Matching Lines)”
[user]$ sed -n '/Alchemist/!p' books.txt

Output (all lines except the one with “Alchemist”):

1) A Storm of Swords, George R. R. Martin, 1216
2) The Two Towers, J. R. R. Tolkien, 352
4) The Fellowship of the Ring, J. R. R. Tolkien, 432
5) The Pilgrimage, Paulo Coelho, 288
6) A Game of Thrones, George R. R. Martin, 864

Simulating tr 'abc' 'xyz' (Translate Characters)

Section titled “Simulating tr 'abc' 'xyz' (Translate Characters)”
[user]$ echo "ABCDE" | sed 'y/ACE/XZE/'

Output:

XBDZE