Как напечатать определенный раздел из файла, если в этом разделе есть ключевое слово поиска [BASH] - PullRequest
0 голосов
/ 01 мая 2018

Ниже приведен фрагмент файла с именем "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]

Я пытаюсь получить полную информацию о книге, если я ищу ее по имени автора.

Пример 1:

Поиск по ключевому слову: Al Avery

Тогда возврат должен быть:

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

Пример 2:

Поиск по ключевому слову: Роберт Ллойд Прегер

Тогда возврат должен быть:

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

Я пробовал это:

#!/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

Но это не работает именно так, как я хочу. Может ли кто-нибудь помочь мне с этим?


EDIT

Обновлена ​​структура файла после обнаружения строки даты. Пытался: awk -v RS = '\ n \ n' "/ $ {ключевое слово} /" infile а также: awk -v RS = -v ключевое слово = "$ ключевое слово" '$ 0 ~ ключевое слово' file.txt Как следует из ответов, приведенных ниже @andlrc и @ αғsнιη, но он печатает много других материалов, которые не связаны между собой. Мое лучшее предположение, что эта строка ломает это:

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

Поскольку верхняя часть этой строки имеет 2 пробела и ниже одного пробела, я думаю, что из-за двух верхних пробелов она не работает должным образом.

Ответы [ 3 ]

0 голосов
/ 01 мая 2018

Я бы использовал awk, просто определите пустую строку как R ecord S , разделитель и поиск строки содержится в любом блоке:

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

или установите RS в пустую строку

awk '/Al Avery/' RS= infile

Как только вам нужно получить блок для ввода пользователя, вы можете сделать:

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

Обратите внимание на использование двойных кавычек вместо одинарных кавычек, что позволяет оболочке сначала раскрыть переменную, а затем использовать ее в awk .


для работы с ключевым словом , если оно содержит обратную косую черту \ или косую черту / и любые другие, вы можете использовать awk следующим образом (для Shell (Bash, ksh, ksh93, mksh, zsh) which supports Pattern Substitution Expansion) :

PATTERN="${keyword//\\/\\\\}" awk '$0 ~ ENVIRON["PATTERN"]' RS= infile
0 голосов
/ 01 мая 2018

Вы можете использовать awk и переменную Record Separator:

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

Вы можете установить переменные для awk с помощью опции -v; -v name=val. В вашем случае нам нужно установить для переменной "ключевое слово" значение переменной bash с тем же именем:

-v keyword="$keyword"

Скрипт awk:

$0 ~ keyword

, который будет сопоставлять весь блок содержимого с регулярным выражением, указанным в переменной "ключевое слово".

Если RS равно нулю, то записи разделяются последовательностями, состоящими из плюс одной или нескольких пустых строк

Источник: $ man awk | awk '/RS is null/' RS=

0 голосов
/ 01 мая 2018

Вы можете использовать команду grep, как показано ниже: -

 grep search_string -A n -B m file.extension

Здесь -A обозначает после строки поиска и -B обозначает перед строкой поиска, поэтому, вероятно, вы можете попробовать с: -

command=$(grep -i -A 2 "$keyword" books.info)  
...