2016-01-13 2 views
0

Я хотел бы использовать bash для файла, чтобы извлечь текст, который находится между двумя строками. Есть уже некоторые ответы на это, например:извлекать текст между несколькими строками в одной строке

Print text between two strings on the same line

Но я хотел бы сделать это для нескольких случаев, иногда на одной и той же линии, иногда на новых линиях. например, начиная с файлом, как это:

\section{The rock outcrop pools experimental system} \label{intro:rockpools} 
contain pools at their summit \parencite{brendonck_pools_2010} that have weathered into the rock over time \parencite{bayly_aquatic_2011} through chemical weathering after water collecting at the rock surface \parencite{lister_microgeomorphology_1973}. 
Classification depends on dimensions \parencite{twidale_gnammas_1963}. 

Я хотел бы получить:

brendonck_pools_2010 
bayly_aquatic_2011 
lister_microgeomorphology_1973 
twidale_gnammas_1963 

Я представляю себе СЭД должен быть в состоянии сделать это, но я не уверен, с чего начать.

+1

Всегда лучше показывать достаточный контекст, чтобы дать некоторую оценку сложности проблемы. Что [anubhava] (https://stackoverflow.com/users/548225/anubhava) [показало] (http://stackoverflow.com/a/34771029), когда я прокомментировал это для более простого ввода. Вероятно, я бы использовал слегка модифицированную версию его команды (grep), которая помещает '\ parencite' перед открытой скобкой, а затем фильтрует выход с помощью' sed' для удаления нежелательного материала. –

ответ

1

Использование grep -oP;

grep -oP '\\parencite\{\K[^}]+' file 
brendonck_pools_2010 
bayly_aquatic_2011 
lister_microgeomorphology_1973 
twidale_gnammas_1963 

Или с помощью гну-AWK:

awk -v FPAT='\\\\parencite{[^}]+' '{for (i=1; i<=NF; i++) { 
    sub(/\\parencite{/, "", $i); print $i}}' file 
brendonck_pools_2010 
bayly_aquatic_2011 
lister_microgeomorphology_1973 
twidale_gnammas_1963 
+0

Спасибо, это доставит мне часть пути. Я обновил этот пример, потому что в файле есть другие вещи со строкой {}, которую я не хочу печатать. Не могли бы вы объяснить, как grep говорят использовать «{» и «}»? когда я использую 'grep -oP 'parencite {\ K [^}] +' файл', он не работает ... – Shearn

+1

@Shearn: в какой системе вы находитесь? У вас есть GNU 'grep' или другой' grep' с поддержкой PCRE? Возможно, вам нужно будет избежать '' '', например. Вам нужно внимательно прочитать инструкцию (удручающе). Когда вы говорите «это не работает», каковы симптомы? Жалобы на регулярное выражение? Просто ничего не возвращаешь? Когда вы сообщаете «не работает», вам нужно быть явным - то, что вы видите, может быть не тем, что видят другие. –

+0

Полностью согласен с '@JonathanLeffler,' не работает' на самом деле не говорит нам, что не работает. Также в отношении вашего отредактированного вопроса, почему 2 значения внутри '{...}' не выводятся? – anubhava

1

Это два этапа экстракта может быть проще понять, без использования Perl регулярного выражения.

$ grep -o "parencite{[^}]*}" cite | sed 's/parencite{//;s/}//' 
brendonck_pools_2010 
bayly_aquatic_2011 
lister_microgeomorphology_1973 
twidale_gnammas_1963 

или, как всегда awk на помощь!

$ awk -F'[{}]' -v RS=" " '/parencite/{print $2}' cite 
brendonck_pools_2010 
bayly_aquatic_2011 
lister_microgeomorphology_1973 
twidale_gnammas_1963 
0

Это может работать для вас (GNU СЭД):

sed '/\\parencite{\([^}]*\)}/!d;s//\n\1\n/;s/^[^\n]*\n//;P;D' file 

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