我想在文件上使用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应该可以做到这一点,但我不知道从哪里开始。
答案 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
删除任何不包含所需字符串的行。用换行符围绕第一次出现并删除并包括第一个换行符。打印并包含以下换行,然后删除打印的内容并重复。