I want a unix command to find the lines between first & last occurence of a word
For example:
let's imagine we have 1000 lines. Tenth line contains word "stackoverflow", thirty fifth line also contains word "stackoverflow".
I want to print lines between 10 and 35 and write it to a new file.
You can use any one of the following command on Unix or Linux to view first 10 lines of a file: head command sed command awk command Perl/Python/Php/Ruby
Printing specific lines from a file is no exception. To display 13th line, you can use a combination of head and tail: Or, you can use sed command: To display line numbers from 20 to 25, you can combine head and tail commands like this: Or, you can use the sed command like this: Detailed explanation of each command follows next.
Type the following sed command to display first 10 lines of a file named “/etc/group”: sed-n 1,10p / etc / group. Type the following sed command to display first 20 lines of a file named “/etc/group”: sed-n 1,20p / etc / group. awk command example to print first 10/20 lines.
Type the following sed command to display first 10 lines of a file named “/etc/group”: sed-n 1,10p / etc / group. Type the following sed command to display first 20 lines of a file named “/etc/group”: sed-n 1,20p / etc / group. awk command example to print first 10/20 lines.
You can make it in two steps. The basic idea is to:
1) get the line number of the first and last match.
2) print the range of lines in between these range.
$ read first last <<< $(grep -n stackoverflow your_file | awk -F: 'NR==1 {printf "%d ", $1}; END{print $1}')
$ awk -v f=$first -v l=$last 'NR>=f && NR<=l' your_file
read first last
reads two values and stores them in $first
and $last
.grep -n stackoverflow your_file
greps and shows the output like this: number_of_line:output
awk -F: 'NR==1 {printf "%d ", $1}; END{print $1}')
prints the number of line of the first and last match of stackoverflow
in the file.And
awk -v f=$first -v l=$last 'NR>=f && NR<=l' your_file
prints all lines from $first
line number till $last
line number.$ cat a
here we
have some text
stackoverflow
and other things
bla
bla
bla bla
stackoverflow
and whatever else
stackoverflow
to make more fun
blablabla
$ read first last <<< $(grep -n stackoverflow a | awk -F: 'NR==1 {printf "%d ", $1}; END{print $1}')
$ awk -v f=$first -v l=$last 'NR>=f && NR<=l' a
stackoverflow
and other things
bla
bla
bla bla
stackoverflow
and whatever else
stackoverflow
By steps:
$ grep -n stackoverflow a
3:stackoverflow
9:stackoverflow
11:stackoverflow
$ grep -n stackoverflow a | awk -F: 'NR==1 {printf "%d ", $1}; END{print $1}'
3 11
$ read first last <<< $(grep -n stackoverflow a | awk -F: 'NR==1 {printf "%d ", $1}; END{print $1}')
$ echo "first=$first, last=$last"
first=3, last=11
If you know an upper bound of how many lines there can be (say, a million), then you can use this simple abusive script:
(grep -A 100000 stackoverflow | grep -B 1000000 stackoverflow) < file
You can append | tail -n +2 | head -n -1
to strip the border lines as well:
(grep -A 100000 stackoverflow | grep -B 1000000 stackoverflow
| tail -n +2 | head -n -1) < file
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With