Replace Mutliple Lines Using Linux awk: Multiline Processing
In this tutorial, you’ll learn how to replace multiple lines using awk in Linux.
We will cover how to replace multiple lines, handle nested blocks, work with patterns, and more.
- 1 Replace Multiple Lines with a Single Line
- 2 Replace Multiple Lines with Multiple Lines
- 3 Replace Multiple Lines Based on a Condition
- 4 Replace Based on Line Numbers
- 5 Pattern Spread Over Multiple Lines
- 6 Replace a Range of Lines with Lines from Another File
- 7 Replace Multiple Lines Using a Variable
- 8 Nested Block Replacement
Replace Multiple Lines with a Single Line
First, let’s consider a sample file customer_data.txt
with the following content:
CustomerID: 001 Name: Alex Plan: Basic CustomerID: 002 Name: Morgan Plan: Premium
Suppose you want to replace the details of each customer which span multiple lines with a single line summary.
Here’s the awk
command to do that:
awk 'BEGIN{RS=""; FS="\n"} {print $1", "$2", "$3}' customer_data.txt
Output:
CustomerID: 001, Name: Alex, Plan: Basic CustomerID: 002, Name: Morgan, Plan: Premium
This command sets the record separator RS
to an empty string and to treat consecutive lines as one record, and the field separator FS
to a newline.
Replace Multiple Lines with Multiple Lines
Let’s say you want to replace each customer’s details with a more detailed format.
Here’s the awk
command to do this:
awk 'BEGIN{RS=""; FS="\n"} {print $1"\n"$2"\n"$3"\nStatus: Active\nPoints: "($3=="Plan: Premium"?250:100)}' customer_data.txt
Output:
CustomerID: 001 Name: Alex Plan: Basic Status: Active Points: 100 CustomerID: 002 Name: Morgan Plan: Premium Status: Active Points: 250
This command treats the file as a single record, splits it into fields based on newline characters, and prints the first three fields followed by “Status: Active” and “Points: X” based on the value of the third field.
If the third field is “Plan: Premium”, it will be 250, otherwise, it will be 100.
Replace Multiple Lines Based on a Condition
Let’s assume customers with more than 200 points should be upgraded to a “Gold” plan.
Original customer_data.txt
content:
CustomerID: 001 Name: Alex Plan: Basic Points: 100 CustomerID: 002 Name: Morgan Plan: Premium Points: 250
To update the plan to “Gold” for customers with points greater than 200, you can use regular expressions to check if the points are greater than 200 ([2-9][0-9][0-9]
):
awk 'BEGIN{RS=""; FS="\n"} {if ($4 ~ /Points: [2-9][0-9][0-9]/) $3="Plan: Gold"; print $1"\n"$2"\n"$3"\n"$4"\n"}' customer_data.txt
Output:
CustomerID: 001 Name: Alex Plan: Basic Points: 100 CustomerID: 002 Name: Morgan Plan: Gold Points: 250
If the condition is met, the plan is changed to “Gold”. Then, it prints the modified details for each customer.
Replace Based on Line Numbers
Suppose you want to update the lines 5 to 7.
Original customer_data.txt
content:
CustomerID: 001 Name: Alex Plan: Basic Points: 100 CustomerID: 002 Name: Morgan Plan: Premium Points: 250
Here’s how it can be done with awk
:
awk 'NR==5,NR==7 {if (NR==5) print "CustomerID: 003"; else if (NR==6) print "Name: Taylor"; else if (NR==7) print "Plan: Standard"; next} 1' customer_data.txt
Output:
CustomerID: 001 Name: Alex Plan: Basic Points: 100 CustomerID: 003 Name: Taylor Plan: Standard Points: 250
In this awk
command, NR==5,NR==7
selects the line number range. For each line in this range, it prints the new information.
The next
command skips the original line, and the 1
at the end prints all lines not in the specified range.
Pattern Spread Over Multiple Lines
Original customer_data.txt
content:
CustomerID: 001 Name: Alex Plan: Basic Points: 100 CustomerID: 002 Name: Morgan Plan: Premium Points: 250
You want to replace the entire block for customers with “Plan: Premium” and “Points: 250” with “Membership: Suspended”. Here’s the awk
command:
awk 'BEGIN{RS=""; FS="\n"} /Plan: Premium\nPoints: 2[5-9][0-9]/ {print "Membership: Suspended\n"; next} {print $0"\n"}' customer_data.txt
Output:
CustomerID: 001 Name: Alex Plan: Basic Points: 100 Membership: Suspended
In this command, awk
is set to treat each customer’s details as a single record.
It searches for records matching the pattern “Plan: Premium” and “Points” between 250 and 299.
If the pattern is found, it replaces the entire block with “Membership: Suspended”.
Replace a Range of Lines with Lines from Another File
Imagine you have two files: customer_data.txt
(our main file) and new_entries.txt
(a file with new customer data).
You want to replace lines 6 to 9 in customer_data.txt
with the content from new_entries.txt
.
Original customer_data.txt
content:
CustomerID: 001 Name: Alex Plan: Basic Points: 100 CustomerID: 002 Name: Morgan Plan: Premium Points: 250
new_entries.txt
content:
CustomerID: 004 Name: Jordan Plan: Standard
Here’s the command to do that:
awk 'NR==6,NR==9{if(!f){system("cat new_entries.txt"); f=1; next} next} 1' customer_data.txt
Output:
CustomerID: 001 Name: Alex Plan: Basic Points: 100 CustomerID: 004 Name: Jordan Plan: Standard
In this command, awk
is used to identify the range of lines (6 to 9) in customer_data.txt
.
When this range is reached, awk
executes the system("cat new_entries.txt")
command which prints the content of new_entries.txt
and replaces the specified range.
The next
command skips the original lines in the range, and the 1
at the end prints all other lines.
Replace Multiple Lines Using a Variable
Suppose you have another file update_info.txt
that contains updated information that needs to replace a specific block of text in customer_data.txt
.
Original customer_data.txt
content:
CustomerID: 001 Name: Alex Plan: Basic Points: 100 CustomerID: 002 Name: Morgan Plan: Premium Points: 250
update_info.txt
contains:
CustomerID: 002 Name: Jordan Plan: Gold Points: 300
You want to replace the details of CustomerID: 002 in customer_data.txt
with the content of update_info.txt
.
First, read the contents of update_info.txt
into a variable:
update=$(<update_info.txt)
Now, use awk
to replace the lines:
awk -v var="$update" 'BEGIN{RS=""; FS="\n"} /CustomerID: 002/ {print var; next} {print $0"\n"}' customer_data.txt
Output:
CustomerID: 001 Name: Alex Plan: Basic Points: 100 CustomerID: 002 Name: Jordan Plan: Gold Points: 300
In this awk
command, the -v
option is used to pass the variable update
containing the new customer details.
awk
then searches for the record containing “CustomerID: 002” and replaces it with the content of update
variable.
Nested Block Replacement
Original customer_data.txt
content:
CustomerID: 001 Name: Alex Plan: Basic Billing: Last Payment: $50 Due Date: 2024-04-05 Contact: Email: alex@example.com Phone: 123-456-7890 CustomerID: 002 Name: Morgan Plan: Premium Billing: Last Payment: $100 Due Date: 2024-04-10 Contact: Email: morgan@example.com Phone: 987-654-3210
Suppose you need to update the nested billing details for “Plan: Premium” customers and the contact details for “CustomerID: 001”.
Here’s an awk
command that can do this:
awk ' BEGIN { RS=""; FS="\n"; OFS="\n" } /CustomerID: 001/ { for (i=1; i<=NF; i++) { if ($i ~ /Contact:/) { inContactBlock = 1 } if (inContactBlock) { if ($i ~ /Email:/) $i = " Email: alex_new@example.com" if ($i ~ /Phone:/) { $i = " Phone: 111-222-3333"; inContactBlock = 0 } } } } /Plan: Premium/ { for (i=1; i<=NF; i++) { if ($i ~ /Billing:/) { inBillingBlock = 1 } if (inBillingBlock) { if ($i ~ /Last Payment:/) $i = " Last Payment: $150" if ($i ~ /Due Date:/) { $i = " Due Date: 2024-05-10"; inBillingBlock = 0 } } } } { print $0"\n" } ' customer_data.txt
Output:
CustomerID: 001 Name: Alex Plan: Basic Billing: Last Payment: $50 Due Date: 2024-04-05 Contact: Email: alex_new@example.com Phone: 111-222-3333 CustomerID: 002 Name: Morgan Plan: Premium Billing: Last Payment: $150 Due Date: 2024-05-10 Contact: Email: morgan@example.com Phone: 987-654-3210
This awk
script uses variables to track if it’s currently within the relevant blocks (Contact
or Billing
) and applies the necessary updates when criteria are met.
Mokhtar is the founder of LikeGeeks.com. He is a seasoned technologist and accomplished author, with expertise in Linux system administration and Python development. Since 2010, Mokhtar has built an impressive career, transitioning from system administration to Python development in 2015. His work spans large corporations to freelance clients around the globe. Alongside his technical work, Mokhtar has authored some insightful books in his field. Known for his innovative solutions, meticulous attention to detail, and high-quality work, Mokhtar continually seeks new challenges within the dynamic field of technology.