Получить список строк между определенными строками в bash - PullRequest
0 голосов
/ 11 января 2020

Учитывая текстовый файл (.tex), который может содержать строки вида "\ cite {alice}", "\ cite {bob}" и т. Д., Я хотел бы написать скрипт bash, который хранит содержимое в квадратных скобках каждой такой строки («Алиса» и «Боб») в новом текстовом файле (скажем, .txt). В выходном файле я хотел бы иметь одну строку для каждого такого содержимого, и я также хотел бы избежать повторений.

Попытки:

  • Я думал о совмещении grep и cut. Из других вопросов и ответов, которые я видел на Stack Exchange, я думаю, что (по чтению по модулю чуть больше) мне удалось получить по крайней мере один такой контент в строке, но я не знаю, как получить все случаи одна строка, если в ней несколько таких строк, и я не видел ни одного вопроса или ответа, дающего подсказки в этом направлении.
  • Я также пытался использовать sed. Вчера я прочитал это руководство , чтобы проверить, не пропустил ли я какую-либо команду basi c sed, но я не видел простого способа сделать то, что я хочу (в руководстве упоминалось, что sed завершен по Тьюрингу, поэтому Я уверен, что есть способ сделать это только с помощью sed, но я не понимаю, как).

Ответы [ 2 ]

2 голосов
/ 11 января 2020

Вы можете использовать grep -o и постобработать его вывод:

grep -o '\\cite{[^{}]*}' file.tex |
sed 's/\\cite{\([^{}]*\)}/\1/'

Если в строке ввода может быть только один \cite, достаточно только сценария sed.

sed -n 's/.*\\cite{\([^{}]*\)}.*/\1/p' file.tex

(отнюдь не невозможно преобразовать это в скрипт, который извлекает несколько вхождений в каждой строке; но удачи в понимании вашего кода через шесть недель.)

Как обычно, добавьте sort -u чтобы удалить любые повторы.

Вот краткая попытка Awk:

awk -v RS='\' '/^cite\{/ {
    split($0, g, /[{}]/)
    cite[g[2]]++ }
  END { for (cit in cite) print cit }' file.tex

Это удобно не печатать дубликаты и тривиально обрабатывает несколько ссылок на строку.

2 голосов
/ 11 января 2020

Как насчет:

grep -oP '(?<=\\cite{)[^}]+(?=})' sample.tex | sort -u > cites.txt
  • -P с GNU grep интерпретирует регулярное выражение как Perl -совместимое ( для взгляд назад и взгляд вперед группы)
  • -o "отпечатки только соответствия (непустые) части совпадающей строки, с каждой такой частью на отдельном выходе строке" (см. manual )
  • регулярное выражение соответствует тексту без фигурных скобок, перед которым стоит \cite{ ( положительный взгляд позади группа (?<=\\cite{)), за которым следует правая фигурная скобка (* 1040) * Положительный Lookafter Группа (?=})).
  • sort -u сортирует и удаляет дубликаты

Для получения дополнительной информации о Lookahead и Lookbehind группы, см. Regular-Expressions.info выделенную страницу .

...