提取字符串之间的子字符串

Extract substrings between strings

我有一个文本如下的文件:

###interest1 moreinterest1### sometext ###interest2###
not-interesting-line
sometext ###interest3###
sometext ###interest4### sometext othertext ###interest5### sometext ###interest6###

我想提取 ### 之间的所有字符串。

我想要的输出是这样的:

interest1 moreinterest1
interest2
interest3
interest4
interest5
interest6

我尝试了以下方法:

grep '###' file.txt | sed -e 's/.*###\(.*\)###.*//g'

这几乎可以工作,但似乎每行只抓取第一个实例,所以我输出中的第一行只抓取

interest1 moreinterest1

而不是

interest1 moreinterest1
interest2

这是实现此目的的单个 awk 命令,它使 ### 字段分隔符并打印每个偶数字段:

awk -F '###' '{for (i=2; i<NF; i+=2) print $i}' file

interest1 moreinterest1
interest2
interest3
interest4
interest5
interest6

这是一个备选方案 grep + sed 解决方案:

grep -oE '###[^#]*###' file | sed -E 's/^###|###$//g'

假设 ### 个标记之间没有 # 个字符。

您可以使用 pcregrep:

pcregrep -o1 '###(.*?)###' file

正则表达式 - ###(.*?)### - 匹配 ###,然后将除换行字符以外的任何零个或更多字符捕获到第 1 组中,尽可能少,然后 ### 匹配###.

o1 选项将仅输出第 1 组值。

参见regex demo online

sed 't x
s/###/\
/;D; :x
s//\
/;t y
D;:y
P;D' file

用换行符替换“###”,D,如果“###”的第二次替换成功,则有条件地分支到 P

使用 GNU awk 进行多字符 RS:

$ awk -v RS='###' '!(NR%2)' file
interest1 moreinterest1
interest2
interest3
interest4
interest5
interest6

这可能适合您 (GNU sed):

sed -n 's/###/\n/g;/[^\n]*\n/{s///;P;D}' file

用换行符替换所有出现的 ###

如果一行包含换行符,则删除第一个换行符之前的所有字符(包括第一个换行符),打印直到并包括以下换行符的详细信息,删除这些详细信息并重复。