-1

Below is a snippet of a file named "books.info":

TITLE and AUTHOR                                                     ETEXT NO.

Aspects of plant life; with special reference to the British flora,      56900
 by Robert Lloyd Praeger

The Vicar of Morwenstow, by Sabine Baring-Gould                          56899
 [Subtitle: Being a Life of Robert Stephen Hawker, M.A.]

Raamatun tutkisteluja IV, mennessä Charles T. Russell                    56898
 [Subtitle: Harmagedonin taistelu]
 [Language: Finnish]

Tom Thatcher's Fortune, by Horatio Alger, Jr.                            56896

A Yankee Flier in the Far East, by Al Avery                              56895
 and George Rutherford Montgomery
 [Illustrator: Paul Laune]

Nancy Brandon's Mystery, by Lillian Garis                                56894

The Junior Classics, Volume 3: Tales from Greece and Rome, by Various    56887


~ ~ ~ ~ Posting Dates for the below eBooks:  1 Mar 2018 to 31 Mar 2018 ~ ~ ~ ~

TITLE and AUTHOR                                                     ETEXT NO.

The American Missionary, Volume 41, No. 1, January, 1887, by Various     56886

Morganin miljoonat, mennessä Sven Elvestad                               56885
 [Author a.k.a. Stein Riverton]
 [Subtitle: Salapoliisiromaani]
 [Language: Finnish]

"Trip to the Sunny South" in March, 1885, by L. S. D                     56884

Balaam and His Master, by Joel Chandler Harris                           56883
 [Subtitle: and Other Sketches and Stories]

I am trying to get the full info for a book if I search it by the author name.

Example1:

Search Keyword: Al Avery

Then return should be:

A Yankee Flier in the Far East, by Al Avery                              56895
 and George Rutherford Montgomery
 [Illustrator: Paul Laune]

Example2:

Search Keyword: Robert Lloyd Praeger

Then return should be:

Aspects of plant life; with special reference to the British flora,      56900
 by Robert Lloyd Praeger

I have tried this:

#!/bin/bash
if [ -f books.info ]
then
    echo Please enter search keyword:
    read keyword
    command=$(grep -i "$keyword" books.info)
    echo $command
else
    echo books.info file is missing
fi

But it is not working exactly they way I want it to. Could anyone please help me with this?


EDIT

Updated the file structure after noticing a date line. Tried: awk -v RS='\n\n' "/${keyword}/" infile and: awk -v RS= -v keyword="$keyword" '$0 ~ keyword' file.txt As suggested by the answers given below by @andlrc and @αғsнιη but it prints out a lot of other stuffs which are not related. My best guess is this line is breaking it:

~ ~ ~ ~ Posting Dates for the below eBooks:  1 Mar 2018 to 31 Mar 2018 ~ ~ ~ ~

Because the top of this line has 2 spaces and below one space, I think because of the top two spaces its not working properly.

Adib
  • 359
  • 1
  • 6
  • 16

3 Answers3

0

You can use grep command like below:-

 grep search_string -A n -B m file.extension

Here -A stand for after search line and -B stand for before search line so probably you can try with:-

command=$(grep -i -A 2 "$keyword" books.info)  
Abhijit Pritam Dutta
  • 5,521
  • 2
  • 11
  • 17
0

I would use awk, just define an empty line as Record Separator and search for a string contains in any block:

awk -v RS='\n\n' '/Al Avery/' infile 

or set RS to empty string

awk '/Al Avery/' RS= infile

Once you need to get the block per user's input, then you could do:

awk -v RS='\n\n' "/${keyword}/" infile

Note the use of double quotes instead of single-quotes which allows shell first do expand the variable then use it in awk.


to works with keyword if it was containing back-slash \ or slash / and any, you could use awk as following (for the Shell (Bash, ksh, ksh93, mksh, zsh) which supports Pattern Substitution Expansion):

PATTERN="${keyword//\\/\\\\}" awk '$0 ~ ENVIRON["PATTERN"]' RS= infile
αғsнιη
  • 2,627
  • 2
  • 25
  • 38
0

You can utilize awk and the Record Separator variable:

awk -v RS= -v keyword="$keyword" '$0 ~ keyword' file.txt

You can set variables for awk via the -v option; -v name=val. In your case we need to set the variable "keyword" to the value of the bash variable of the same name:

-v keyword="$keyword"

The awk script is:

$0 ~ keyword

which will match the whole block of content against the regex provided in the variable "keyword".

If RS is null, then records are separated by sequences consisting of a plus one or more blank lines

Source: $ man awk | awk '/RS is null/' RS=

Andreas Louv
  • 46,145
  • 13
  • 104
  • 123