Unix Sed Tutorial: Multi-Line File Operation with 6 Practical Examples
Linux Sed Examples for Multiple File Line OperationsAs part of our on going UNIX sed tutorial series earlier we covered the printing, deletion, substitution, file write, file manipulation commands etc., with the single line in the pattern space.
In this article let us review how to do the multi-line operation in Sed.
Do you remember the Sed working methodology which we learned in our first sed tutorial ?. In that article we explained that Sed reads line by line, removes any trailing new lines, places a line in a pattern space buffer, process as per the given commands and prints the pattern space.
In case, if you want to delete all the newlines in a file, you cannot use the following method. Because newline is already removed and placed in the pattern space:
$ sed 's/\n//' filename or $sed 's/\n/ENDOFLINE\n/' filename
For situations like this sed multi-line is appropriate. Sed provides the command “N” for Multi-Line Operations.
N command reads a next line from the input, Append next line to pattern space. Next line is separated from the original pattern space by a newline character.
Let us first create thegeekstuff.txt file that will be used in all the examples mentioned below.:
$ cat thegeekstuff.txt
Note: There are two consecutive blank lines in the above input. ( 5th and 6th line ).
Sed Example 1. Join Two Consecutive Lines
$ sed -e '{
N
s/\n/ @ /
}' thegeekstuff.txt
In the above example,
- The curly braces “{” and “}” used to group the commands. The curly braces and sed commands must be on the seperate lines.
- Sed reads the first line and place it in the pattern space, N command reads the next line and appends with the pattern space i.e first line seperated by newline. So now pattern space will have firstlinensecondline.
- Next substitution of n to space@space and it prints the pattern space content as its sed default behaviour. So consecutive lines are joined and delimited by ” @ “
Sed Example 2. Number each non-blank line of a file
As mentioned in our previous article, = is a command to get a line number of a file.:
$ sed '/./=' thegeekstuff.txt | sed 'N; s/\n/ /'
- The first sed command prints the line number and prints the original line in a next line if it is not a blank.( Execute it and see the output of the first sed command ).
- Next sed command is just appends pair of lines.
Sed Example 3. Delete Two Consecutive Blank Lines from Input
$ sed '/^$/{
N
/^\n$/d
}' thegeekstuff.txt
If the line is blank, read and appends the next line, /^n$/ represents, two lines are empty,n is added by N command. Then just delete the pattern space and start the next cycle using command ‘d’.
Sed Example 4. Delete Last 2 Lines of a file
Before viewing this example you must aware of two interesting sed command.
- P – which prints the first line of a pattern space. (till first n).
- D – Delete first line from the pattern space. Control then passes to the top of the script.
$ sed 'N;$!P;$!D;$d' thegeekstuff.txt 1. Reads the first line and place it in the pattern space. 2. N command reads the next line and append to pattern space seperated by newline. (Now firstline\nsecond line) 3. If it not reaches the last line($), print the first line and delete the first line alone from the pattern space. Then cycle starts again. 4. Like this it joins 2nd\n3rd lines, 3rd\n4th lines and goes on. 5. Atlast when it has 9th\n10th line in a pattern space, it reaches $ so it just deletes the pattern space. ($!P and $!D wont print and delete if it is $).
Sed Example 5. Print Last 2 Lines of a file
$ sed '$!N;$!D' thegeekstuff.txt
The above joins and deletes each line until last two lines are there in the pattern space. When it reaches $, prints the pattern space which will have only last two lines. Sed Example 6. Delete Duplicate, Consecutive Lines from a file
The below command checks each line joined with the next line, check if both are same then it doesn’t the print pattern space(!P), just delete the first line from the pattern space. So only one line will be remaining in the pattern space.
$ sed '$!N; /^\(.*\)\n\1$/!P; D' thegeekstuff.txt
