在同一行上的多个字符串之间获取文本

时间:2016-01-13 15:45:15

标签: bash awk sed grep

我想在文件上使用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

我想sed应该可以做到这一点,但我不知道从哪里开始。

3 个答案:

答案 0 :(得分:1)

使用grep -oP;

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

或使用gnu-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

答案 1 :(得分: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

答案 2 :(得分:0)

这可能适合你(GNU sed):

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

删除任何不包含所需字符串的行。用换行符围绕第一次出现并删除并包括第一个换行符。打印并包含以下换行,然后删除打印的内容并重复。