Sed script to delete the first two lines of a file if they are empty

I am trying to write a rather brief sed script to delete the first two lines of a file only if they are empty, so the following file:

> cat myfile.in Line 3 Line 5 

A file appears with three lines:

 > cat myfile.out Line 3 Line 5 

This has to do with string range combining and pattern matching, and I just can't find any examples. I would also be interested if anyone could offer and equally (or more) consult an alternative to Perl. Many thanks.

Footnote

I should add that I tried 1,2{/^$/d} , which worked fine on Linux, but on AIX I got:

 sed: 0602-404 Function 1,2{/^$/d} cannot be parsed. 

and on Solaris I got:

 sed: command garbled: 1,2{/^$/d} 

This is a hit because this code should work on both AIX and Solaris, but not Linux! Shame!

+4
source share
7 answers

I think this should work with sed (if you want to delete both first lines if both are empty):

 sed '1,1{N;/^\n$/d}' 

ie: 1,1 = go to the first line, N = add the next line to the pattern space, ^\n$/d = delete these two lines if they are empty.

If you want to delete the first two lines, if they are empty (regardless of the other line), you can do:

 sed '1,2/^$/d' 
+2
source

Here is one way to do it in Perl:

 perl -ne 'print if $. > 2 or $_ ne "\n"' <myfile.in >myfile.out 

If you want to allow extra spaces on empty lines:

 perl -ne 'print if $. > 2 or /\S/' <myfile.in >myfile.out 

This next version is a little different. It deletes only the initial empty lines (up to 2). If the first line is not empty and the second, both lines will be printed. (I thought about this before you answered my comment, and I like it, and the next person who happens on this question may have different requirements.)

 perl -ne 'print if $started ||= $. > 2 || /\S/' 

$started ||= means that after printing starts, it does not stop.

+8
source

Not perl monk, but I would do it in Perl (maybe there is a better way):

 $_ = <> or exit 0; print unless /^\s*$/; $_ = <> or exit 0; print unless /^\s*$/; print while <>; 
+3
source

This can be done in a simple awk script as follows:

 awk 'NR>2 || $0 != ""' file.txt 

EDIT: Since awk was not considered a common tool to solve the problem, here is one sed command that works on Mac and Linux:

 sed '/^$/{1,2d;}' file.txt 

OR

 sed '1,2s/^$/ ~@ #%-=/; /^ ~@ #%-=$/d' file.txt 

The intended file does not have the line ~@ #%-= (which can be changed to any other arbitrary text).

+2
source

This might work for you:

 sed -e '1{/^$/d}' -e '2{/^$/d}' file 
+2
source

You can use ed text editor:

 $ echo -e '1,2g/^$/d\n%p' | ed -s input.txt 

If you want to save the result: (change %p to w )

 $ echo -e '1,2g/^$/d\nw' | ed -s input.txt 
0
source

You can do it awk this way

 cat 1.txt | awk '{if(NR>2){print $0;}}' 
-3
source

Source: https://habr.com/ru/post/1398984/


All Articles