Ниже приведен фрагмент файла с именем "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:
Ключевое слово для поиска: Аль Эйвери
Тогда возврат должен быть:
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
Но это работает не так, как я хочу. Может ли кто-нибудь помочь мне с этим?
РЕДАКТИРОВАТЬ
Обновил структуру файла после того, как заметил строку даты. Пытался: awk -v RS = '\ n \ n' "/ $ {keyword} /" infile а также: awk -v RS = -v keyword = "$ keyword" '$ 0 ~ keyword' file.txt Как следует из ответов, приведенных ниже @andlrc и @ αғsнιη, но он распечатывает много других материалов, которые не связаны. Я предполагаю, что эта строка нарушает его:
~ ~ ~ ~ Posting Dates for the below eBooks: 1 Mar 2018 to 31 Mar 2018 ~ ~ ~ ~
Поскольку в верхней части этой строки есть 2 пробела, а под одним пробелом, я думаю, из-за двух верхних пробелов он не работает должным образом.
Вы можете использовать команду grep
, как показано ниже: -
grep search_string -A n -B m file.extension
Здесь -A
обозначает строку после поиска, а -B
обозначает строку до строки поиска, поэтому, вероятно, вы можете попробовать: -
command=$(grep -i -A 2 "$keyword" books.info)
это верно для "Example1", а что насчет Example2?
Я бы использовал awk
, просто определите пустую строку как рecord Separator и найдите строку, содержащуюся в любом блоке:
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
Можно установить RS
в ноль с тем же результатом: awk -v RS= '/Al avery/' infile
См. man awk | awk '/RS is null/' RS=
Что произойдет, если переменная "ключевое слово" будет содержать косую черту (/
)?
Вы можете использовать awk и переменную разделителя записей:
awk -v RS= -v keyword = "$keyword" '$0 ~ keyword' file.txt
Вы можете установить переменные для awk с помощью опции -v
; -v name=val
. В вашем случае нам нужно установить переменную keyword в значение одноименной переменной bash:
-v keyword = "$keyword"
Скрипт awk:
$0 ~ keyword
который будет сопоставлять весь блок содержимого с регулярным выражением, указанным в переменной "keyword".
If RS is null, then records are separated by sequences consisting of a plus one or more blank lines
Источник: $ man awk | awk '/RS is null/' RS=
Нет необходимости передавать ключевое слово в качестве переменной awk, мы можем использовать двойные кавычки вместо одинарных кавычек для awk, тогда оболочка выполнит расширение переменной, см. Мой ответ выше.
@ αғsнιη Не получится, если "ключевое слово" содержит косую черту.
Правильно, а что если в вашем не было обратных косых черт "\"
:)
Предлагаю взглянуть на
sed
.