这是正文:
* Tue This is the first line
– info 1
– info 2
– info 3
* Wed This is not to be included
该文本的输出应该是这样的:
* Tue This is the first line
– info 1
– info 2
– info 3
注意:我尝试过 awk 和 sed 但未能得出我的输出。问题是 START 和 END 是相同的“*”(星号),并且第一个应该包含在输出中。
答案1
我希望我正确理解这一点。该脚本将从第二行开始*
直到缓冲区末尾删除所有内容,从而从示例中生成所需的输出:
sed -n 'H;1h;$x;$s/\(\*[^*]*\)\n\*.*$/\1/p'
说明 将所有行 ( H
) 添加到保持缓冲区。对于最后一行交换保持和模式缓冲区 ( $x
),因此您将整个文件作为一个模式。在此模式中,要保留的部分设置\(\)
并保留 ( \1
),而换行符中的所有内容都*
将被删除。
这符合您的描述,但如果它不符合所有可能的示例,您可以修改脚本。
答案2
perl -lne 'if ( m?^\*? ... m?^\*? ) { print if !// || !$a++ }'
sed -e '
/^\*/!d
:loop
$q; N
/\n\*/!bloop
s/\(.*\)\n.*/\1/;q
'
sed -e '
/^\*/!d
:loop
n
//!bloop
Q
'
答案3
将示例文本保存到变量:
$ SAMPLE=$(cat <<EOF
* Tue This is the first line
– info 1
– info 2
– info 3
* Wed This is not to be included
* Tue This is the first line
– info 1
– info 2
– info 3
* Wed This is not to be included
EOF
)
用于awk
处理您的$SAMPLE
:
$ awk '{if($1~"\*"){if(p==1){p=0;next}else{p=1}}if(p==1){print $0}}' <<<"$SAMPLE"
* Tue This is the first line
– info 1
– info 2
– info 3
* Tue This is the first line
– info 1
– info 2
– info 3
编辑
正如评论中所建议的,有一个令人惊讶的优雅awk
解决方案:
$ awk '/^\*/{p=!p};p' <<<"$SAMPLE"
* Tue This is the first line
– info 1
– info 2
– info 3
* Tue This is the first line
– info 1
– info 2
– info 3
怎么运行的:
/^\*/{p=!p};
- 这会将 的值交替p
为1
和。当第一次找到正则表达式时0
,它将变为。第二次找到时,它将变为,依此类推。1
/^\*/
p
0
p
- 这相当于p{print}
.由于print
是 中的默认操作,因此当前提条件计算为该值时(在本例中当变为时awk
),它将始终打印。true
p
1