tags:

views:

157

answers:

8

What's the best shell command to output the lines of a file until you encounter the first blank line? For example:

output these
lines

but do not output anything after the above blank line
(or the blank line itself)

awk? something else?

A: 

Here's a solution using Perl:

#! perl

use strict;
use warnings;

while (<DATA>) {
    last if length == 1;
    print;
}

__DATA__
output these
lines

but don't output anything after the above blank line
(or the blank line itself)
chardin
perl -pe 'exit if m/^$/' (filename)
Joe
Joe, your Perl solution is nice. I wish I had thought of it.
chardin
@Joe: `m` is redundant, see my answer http://stackoverflow.com/questions/1603389/shell-simple-way-to-get-all-lines-before-first-blank-line/1603576#1603576
J.F. Sebastian
+1  A: 

With sed:

sed '/^$/Q' <file>

Edit: sed is way, way, way faster. See ephemient's answer for the fastest version.

To do this in awk, you could use:

awk '{if ($0 == "") exit; else print}' <file>

Note that I intentionally wrote this to avoid using regular expressions. I don't know what awk's internal optimizations are like, but I suspect direct string comparison would be faster.

Jefromi
+4  A: 
sed -e '/^$/,$d' <<EOF
this is text
so is this

but not this
or this
EOF
themis
Probably a little clearer to write this as: `sed -e '/^$/,$d' <file>`. Also, if you happen to have huge files (or a lot of them), it could be an issue that this reads the entire file. Otherwise, nice and short!
Jefromi
I have added a sed solution to my answer which does not read the entire file.
Jefromi
I like ephemient's sed -e '/./!Q' solution, too.
themis
+2  A: 

Awk solution

awk '/^$/{exit} {print} ' <filename>
Vereb
`1` is shorter than writing `{print}` and does the same thing.
ephemient
+1  A: 

A couple of Perl one-liners

$ perl -pe'last if /^$/' file..

$ perl -lpe'last unless length' file..
J.F. Sebastian
+4  A: 

More awk:

awk -v 'RS=\n\n' '1;{exit}'

More sed:

sed -n -e '/./p;/./!q'
sed -e '/./!{d;q}'
sed -e '/./!Q'   # thanks to Jefromi

How about directly in shell?

while read line; do [ -z "$line" ] && break; echo "$line"; done

(Or printf '%s\n' instead of echo, if your shell is buggy and always handles escapes.)

ephemient
Nice awking! The second sed can be shortened to `'/./!Q'` - `Q` quits immediately, without auto-printing. +1
Jefromi
I tried some timings: `'/./!Q'` 2.5s; `'/./!{d;q}'` 5.5s; `'/^$/Q'` 7.5s.
Jefromi
Awesome, thanks!
ephemient
+2  A: 
# awk '!NF{exit}1' file
output these
lines
ghostdog74
+1 for being very compact. I love it.
Hai Vu
A: 

Another Perl solution:

perl -00 -ne 'print;exit' file
perl -00 -pe 'exit if $. == 2' file
glenn jackman