SoFunction
Updated on 2025-03-09

The difference between sed mode space and temporary storage space

The sed editor processes the file line by line and prints the output to the screen. The sed command reads the currently processed line into the pattern space for processing. After sed executes all commands on this line, it prints the processed line to the screen (unless the previous command deletes the line). After sed processes one line, it deletes it from the pattern space, and then reads the next line into the pattern space for processing and display. After processing the last line of the file, sed ends running. sed processes the file in the temporary buffer (mode space), so the original file will not be modified unless the specified -i option is displayed.

Commands related to pattern space and hold space:

n Output mode space line, read the next line that replaces the current mode space, and execute the next processing command instead of the first command.
N Read the next line and append it to the pattern space line. At this time, there are two lines in the pattern space.
h Copy the lines in the pattern space to the temporary storage space.
H Append lines in the pattern space to the temporary storage space.
g Replace the line of the pattern space with the content of the temporary space.
G After appending the content of the temporary space to the line of the pattern space.
x Swap the contents of the temporary space with the current row in the pattern space.
! Applies commands to all lines except the selected line.

Note: A blank line is stored by default in the temporary storage space.

Here are some examples:

cat datafile
111111111111 aaa
222222222222 bbb
333333333333 ccc
444444444444 ddd
555555555555 eee
666666666666 fff

Add an empty line after each line:

sed 'G' datafile
111111111111 aaa

222222222222 bbb

333333333333 ccc

444444444444 ddd

555555555555 eee

666666666666 fff

The aaa line is read into the mode space, execute G, add an empty line after this line, and then print the mode space, the same applies to other lines.

Add an empty line after matching the line:

sed '/ccc/G' datafile
111111111111 aaa
222222222222 bbb
333333333333 ccc

444444444444 ddd
555555555555 eee
666666666666 fff

Add an empty line before matching the line:

sed '/ccc/{x;p;x;}' datafile
111111111111 aaa
222222222222 bbb

333333333333 ccc
444444444444 ddd
555555555555 eee
666666666666 fff

Changes in temporary space and mode space before and after command execution:

Commands Stage Space
x
p
x

(Note: Abbreviate the line where ccc is located as ccc)

Delete even lines:

sed '{n;d;}' datafile
111111111111 aaa
333333333333 ccc
555555555555 eee

After executing n, print the first line, then read in the second line and execute the d command, that is, delete this line; then print the third line when executing n, then read in the fourth line and execute the d command, and so on.

Add a new line after an even number of lines:

sed '{n;G;}' datafile
111111111111 aaa
222222222222 bbb

333333333333 ccc
444444444444 ddd

555555555555 eee
666666666666 fff

After executing n, output the first line to the standard output, then the second line enters the mode space. According to the previous explanation of G, a blank line will be inserted after the second line and then output; then executing n will output the third line to the standard output, then the fourth line enters the mode space, inserts the blank line, and so on.
Corresponding: sed '{n;n;G;}' datafile indicates that a blank line is inserted after lines 3, 6, 9, 12,… of the file.

Put even lines empty:

sed '{n;g;}' datafile
111111111111 aaa

333333333333 ccc

555555555555 eee

After executing n, print the first line, then read the second line and execute the g command. The g command replaces the current mode space with the temporary space content (null), that is, the second line is empty. Other lines and so on.

Merge even lines to the previous line:

sed '{N;s/\n/\t/;}' datafile
111111111111 aaa 222222222222 bbb
333333333333 ccc 444444444444 ddd
555555555555 eee 666666666666 fff

After executing N, appending the second line to the first line of the pattern space, the pattern space is then replaced by two lines, and then performing replacement (s) to replace the first newline character with tab. Other lines and so on.

The additional line number is roughly equivalent to cat -n datafile:

sed = datafile
1
111111111111 aaa
2
222222222222 bbb
3
333333333333 ccc
4
444444444444 ddd
5
555555555555 eee
6
666666666666 fff

sed = datafile |sed '{N;s/\n/\t/;}'
1 111111111111 aaa
2 222222222222 bbb
3 333333333333 ccc
4 444444444444 ddd
5 555555555555 eee
6 666666666666 fff

The last 2 lines of the output file are equivalent to tail -2 datafile

sed '{$!N;$!d;}' datafile
555555555555 eee
666666666666 fff

sed '{$!N;$!d;}' : For the line before the penultimate line of the file, after N appends the next line of the current line to the pattern space, D deletes the content of the pattern space; when the penultimate line, appends the last line below the penultimate line, and then the last line does not execute d (! For the selected line - this is the last line, execute the command outside the line), so the last two lines of the file are saved.

Display the file lines in reverse order, which is equivalent to the tac command:

sed '{1!G;h;$!d;}' datafile
666666666666 fff
555555555555 eee
444444444444 ddd
333333333333 ccc
222222222222 bbb
111111111111 aaa

1!G means that except for the first line, all the lines execute the G command; $!d means that except the last line, all the lines execute the d command.

Take a look at the changes in the temporary storage space and pattern space during the execution of the sed '{1!G;h;$!d;}' command:

Processing Line Commands Stage Space                                                                                                                           �
First line                                                                                                                                                                                                                                                              �
Second line                                                                                                                              �
The last line    G;h                   Before execution:eee\n…aaa\n After execution:ffff\n…bbb\n\aaa\n

(Note: The abbreviation of each line)