помогите с регулярным выражением - извлечение текста

Предположим, у меня есть несколько текстовых файлов (f1.txt, f2.txt,...), которые выглядят примерно так:

@article {paper1,
author = {some author},
title = {some {T}itle} ,
journal = {journal},
volume = {16},
number = {4},
publisher = {John Wiley & Sons, Ltd.},
issn = {some number},
url = {some url},
doi = {some number},
pages = {1},
year = {1997},
}

Я хочу извлечь содержимое заголовка и сохранить его в переменной bash (назовем ее $title), то есть в примере «некоторый {T}itle». Обратите внимание, что в первом наборе фигурных скобок могут быть фигурные скобки. Кроме того, вокруг «=» может не быть пробела, а перед «title» пробелов может быть больше.

Большое спасибо. Мне просто нужен рабочий пример того, как извлечь это, и я могу извлечь другие вещи.


person Vinh Nguyen    schedule 02.03.2011    source источник


Ответы (3)


Попробуйте это:

title=$(sed -n '/^[[:blank:]]*title[[:blank:]]*=[[:blank:]]*{/ {s///; s/}[^}]*$//p}' inputfile)

Объяснение:

  • /^[[:blank:]]*title[[:blank:]]*=[[:blank:]]*{/ { - If a line matches this regex
    • s/// - delete the matched portion
    • s/}[^}]*$//p - удалить последнюю закрывающую фигурную скобку и все символы, не являющиеся закрывающей фигурной скобкой, до конца строки и вывести
  • } - конец, если
person Dennis Williamson    schedule 02.03.2011
comment
+1 После того, как я изменил свой скрипт, чтобы позаботиться о случае, когда в значении может быть запятая, я получил именно ваш скрипт. Я сказал ОП принять ваше, но я думаю, что вы должны обернуть его title=$(sed ...), чтобы полностью удовлетворить его требования. - person SiegeX; 03.03.2011

title=$(sed -n '/title *=/{s/^[^{]*{\([^,]*\),.*$/\1/;s/} *$//p}' ./f1.txt)
  1. /title *=/: Воздействовать только на строки, в которых есть слово «заголовок», за которым следует «=» после произвольного количества пробелов.
  2. s/^[^{]*{\([^,]*\),.*$/\1/: В начале строки ищите первый символ '{'. С этого момента сохраняйте все, что вы найдете, пока не нажмете запятую ','. Замените всю строку всем, что вы сохранили
  3. s/} *$//p: удалите закрывающую фигурную скобку '}' вместе со всеми пробелами и распечатайте результат.
  4. title=$(sed -n ... ): сохранить результат трех вышеуказанных шагов в переменной bash с именем title
person SiegeX    schedule 02.03.2011
comment
Спасибо. Однако что, если в том, что я хочу захватить, есть запятые? Тогда это не работает из-за логики первой запятой. Как мы можем использовать гибкость дополнительных запятых? Спасибо - person Vinh Nguyen; 02.03.2011
comment
@Vinh, вы должны принять ответ Денниса, потому что после того, как я изменил свой сценарий, чтобы позаботиться о случае, когда в имени может быть запятая, я получил именно его сценарий. Единственное, что вам нужно сделать, это обернуть его сценарий в $(), как мой. - person SiegeX; 03.03.2011

Есть определенно более элегантные способы, но в 2:40:

title=`cat test | grep "^\s*title\s*=\s*" | sed 's/^\s*title\s*=\s*{?//' | sed 's/}?\s*,\s*$//'`

Grep для интересующей нас строки, зачистите все вплоть до открывающего завитка включительно, затем зачистите все от последнего завитка до конца строки

person Shay Rojansky    schedule 02.03.2011