Shell: insert a blank / new line two lines above the picture

To add an empty line above each line that matches your regular expression, you can use:

sed '/regexp/{x;p;x;}' 

But I want to add an empty line, not one line above, but two lines above the line that matches my regular expression.

The sample that I will match is the zip code in the address bar.

Here is a text formatting snippet:

random information (owned by a previous business)
The name of the company
business address

For example:

Languages โ€‹โ€‹spoken: English
Arnold Cove, Nfld (South To Clarenville)
Neal Road, Arnolds Cove, NL, A0B1N0

I want to add a new line above the company name:

Languages โ€‹โ€‹spoken: English

Arnold Cove, Nfld (South To Clarenville)
Neal Road, Arnolds Cove, NL, A0B1N0

+6
python text awk perl sed
source share
6 answers

Something a bit like your original sed approach:

 sed '/regexp/i\ $H x' 

The basic idea is to print everything, one line delay ( x change hold space and spaces - print implicitly). This needs to be done because until we check whether the next line matches the regular expression, we do not know whether i should translate the new line or not.

(There is just a trick in $ H to do the last line print. It adds the last line to the storage buffer, so the final implicit print command prints it too.)

+5
source share

More readable Perl and safely handles multiple files.

 #!/usr/bin/env perl use constant LINES => 2; my @buffer = (); while (<>) { /pattern/ and unshift @buffer, "\n"; push @buffer, $_; print splice @buffer, 0, -LINES; } continue { if (eof(ARGV)) { print @buffer; @buffer = (); } } 
+7
source share

Plain:

 sed '1{x;d};$H;/regexp/{x;s/^/\n/;b};x' 

Describe him

 #!/bin/sed # trick is juggling previous and current line in hold and pattern space 1 { # at firs line x # place first line to hold space d # skip to end and avoid printing } $H # append last line to hold space to force print /regexp/ { # regexp found (in current line - pattern space) x # swap previous and current line between hold and pattern space s/^/\n/ # prepend line break before previous line b # jump at end of script which cause print previous line } x # if regexp does not match just swap previous and current line to print previous one 

Edit : A slightly simpler version.

 sed '$H;/regexp/{x;s/^/\n/;b};x;1d' 
+3
source share
 perl -ne 'END{print @x} push@x ,$_; if(@x>2){splice @x,1,0,"\n" if /[[:alpha:]]\d[[:alpha:]]\s?\d[[:alpha:]]\d/;print splice @x,0,-2}' 

If I cat my file into this, I get what you want ... it's ugly, but you want a shell (that is, one-line) :-) If I did this in full, I would be able to clear it to do its readable. :-)

+2
source share

This uses an approach that works for Python.

 import sys def address_change( aFile ): address= [] for line in aFile: if regex.match( line ): # end of the address print address[0] print print address[1:] print line address= [] else: address.append( line ) address_change( sys.stdin ) 

This allows you to reformat the full address for your heart content. You can expand this to create the Address class if your formatting is complicated.

+1
source share

I tried

 sed '/regexp/a\\n' 

but he inserted two new lines. If this does not bother you, take it.

echo -e "a \ nb \ nc" | sed '/ ^ a $ / a \ n'
a

b
c

Edit: Now that you state that you need to insert two lines above the corresponding regexp, the proposed regular expression will not work.

I'm not even sure if sed will work at all, since you need to remember the last lines. Sounds like work for a higher level language like python or perl :-)

0
source share

All Articles