Reputation: 1119
I have a file like this:
a sth1
a sth2
b sth3
b sth4
c sth5
c sth6
c sth6
d sth8
d sth9
d sth10
X sth10
X sth11
and I woul'd like to recive all lines between first line starting with b
and last line starting with d
:
b sth3
b sth4
c sth5
c sth6
c sth6
d sth8
d sth9
d sth10
I have a sed command sed -n /"b"/,/"d"/p final.txt
but the output is:
b sth3
b sth4
c sth5
c sth6
c sth6
d sth8
My question is how to modify sed command to get expected result ?
Im sorry for beeing not precise. I should ask about this:
I have a file like this:
127.0.0.1 - - [04/Jun/2014:11:21:01 +0200] STH1
127.0.0.1 - - [04/Jun/2014:11:21:01 +0200] STH2
127.0.0.1 - - [04/Jun/2014:11:21:01 +0200] STH3
127.0.0.1 - - [04/Jun/2014:12:21:01 +0200] STH4
127.0.0.1 - - [04/Jun/2014:12:21:01 +0200] STH5
127.0.0.1 - - [04/Jun/2014:12:21:01 +0200] STH6
127.0.0.1 - - [04/Jun/2014:12:21:01 +0200] STH7
127.0.0.1 - - [04/Jun/2014:13:21:01 +0200] STH8
127.0.0.1 - - [04/Jun/2014:13:21:01 +0200] STH9
127.0.0.1 - - [04/Jun/2014:13:21:01 +0200] STH10
127.0.0.1 - - [04/Jun/2014:14:21:01 +0200] STH11
127.0.0.1 - - [04/Jun/2014:14:21:01 +0200] STH12
127.0.0.1 - - [04/Jun/2014:15:21:01 +0200] STH13
127.0.0.1 - - [04/Jun/2014:15:21:01 +0200] STH14
and I want extract content between first line containing $startDate="04/Jun/2014:12:21:01"
and last line containing $endDate="04/Jun/2014:13:21:01"
. The result should be:
127.0.0.1 - - [04/Jun/2014:12:21:01 +0200] STH4
127.0.0.1 - - [04/Jun/2014:12:21:01 +0200] STH5
127.0.0.1 - - [04/Jun/2014:12:21:01 +0200] STH6
127.0.0.1 - - [04/Jun/2014:12:21:01 +0200] STH7
127.0.0.1 - - [04/Jun/2014:13:21:01 +0200] STH8
127.0.0.1 - - [04/Jun/2014:13:21:01 +0200] STH9
127.0.0.1 - - [04/Jun/2014:13:21:01 +0200] STH10
$startDate
and $endDate
are variables in BASH script. I really apologise for my last post where I asked not precise question...
Upvotes: 1
Views: 108
Reputation: 289495
If your file is unsorted, then it is necessary to loop twice: first to know the lines to print and then to print them:
$ awk 'FNR==NR {if (/^b/ && !b) {b=NR} if (/^d/) {d=NR}; next} (FNR>=b && FNR<=d)' file file
b sth3
b sth4
c sth5
c sth6
c sth6
d sth8
d sth9
d sth10
As per comments, if you want to define the b
and d
as a parameter you can use:
-v start="your_start_date"
-v end="your_end_date"
See an example with current data:
$ awk -v start="b" -v end="d" 'FNR==NR {if ($1 == start && !b) {b=NR} if ($1 == end) {d=NR}; next} (FNR>=b && FNR<=d)' file file
b sth3
b sth4
c sth5
c sth6
c sth6
d sth8
d sth9
d sth10
Based on your last update:
$ startDate="04/Jun/2014:12:21:01"
$ endDate="04/Jun/2014:13:21:01"
$ awk -v start="$startDate" -v end="$endDate" 'FNR==NR {if ($0 ~ start && !b) {b=NR} if ($0 ~ end) {d=NR}; next} (FNR>=b && FNR<=d)' file file
127.0.0.1 - - [04/Jun/2014:12:21:01 +0200] STH4
127.0.0.1 - - [04/Jun/2014:12:21:01 +0200] STH5
127.0.0.1 - - [04/Jun/2014:12:21:01 +0200] STH6
127.0.0.1 - - [04/Jun/2014:12:21:01 +0200] STH7
127.0.0.1 - - [04/Jun/2014:13:21:01 +0200] STH8
127.0.0.1 - - [04/Jun/2014:13:21:01 +0200] STH9
127.0.0.1 - - [04/Jun/2014:13:21:01 +0200] STH10
Upvotes: 0
Reputation: 1334
Use this sed command to get the expected result.
$ sed -n '/^b/,/^d/{p;d};/^d/p' `input_filename`
Upvotes: 0
Reputation: 10039
sed -n '/^b/p;/^c/p;/^d/p' YourFile
assuming it is sort like your sample. take care of missing line with b
or d
Upvotes: 0
Reputation: 195029
if your file is already sorted by the 1st column (the a, b, c...
), this works for your example:
awk '$1>="b"&&$1<="d"' file
the "b"
and "d"
here could be other string, like abc
and zzz
as long as the file was sorted, it should work.
based on your example, this sed line worked here:
sed -n '/^b/,/^d/{/^[^d]/p};/^d/p' file
Upvotes: 4
Reputation: 41446
Here is an awk
awk '/^b/ {f=1} /^d/ {g=1} g && !/^d/ {f=0} f' file
b sth3
b sth4
c sth5
c sth6
c sth6
d sth8
d sth9
d sth10
Upvotes: 0
Reputation: 784908
Here is a way you can do it in awk
:
awk '/^b/{p=1} /^d/{p=2} p==2 && substr($1, 1, 1) != "d" {exit} p' file
b sth3
b sth4
c sth5
c sth6
c sth6
d sth8
d sth9
d sth10
Upvotes: 0