当--AnchorABC
重复1次时,有关如何在--Anchor<not ABC>
和--AnchorABC
之间获取内容的任何想法?
示例输入:
It
is
a
lovely
day
--AnchorABC something
--AnchorABC something else
--AnchorABC yet something else
Hey
how
are
you
--AnchorXYZ
I
am
fine
--AnchorLMN
示例输出(删除最后一行不是非常重要):
--AnchorABC something
--AnchorABC something else
--AnchorABC yet something else
Hey
how
are
you
--AnchorXYZ
如果偶数--AnchorABC
那么它很容易(尽管是hacky),但是有一个奇数,那么黑客就会崩溃。使用sed,我试图在--AnchorABC
和以--
开头但不的行具有AnchorABC的行之间进行模式范围,但是sed没有负向前瞻。
基本上问题陈述是:在第一次出现的模式之间打印所有行,这些模式以--
开头,并且在--
之后有一个键,然后是一个任意结尾,下一次出现一行从模式--
开始,但使用不同的密钥。或者另一种方式:
--AnchorABC
--AnchorABC
或任何不以--
开头的内容,请将其打印--Anchor
但不是--AnchorABC
,请停止编辑:明确表示第二个锚键未知,“键”可以是多个字符。
答案 0 :(得分:3)
使用awk:
awk '/^--AnchorA/{l=1} /^--Anchor[^A]/{l=0; print; exit}l' file.txt
或者更简单,感谢@iamuser的想法:
awk '/^--AnchorA/{l=1}; l; /^--Anchor[^A]/{exit}' file.txt
//{}
=正则表达式条件和执行/^--AnchorA/{l=1}
表示如果正则表达匹配则分配l=1
l
是一个awk技巧:它意味着true
,而在真实情况下,awk默认是打印。//{}
同样的事情,但我们使用负范围来排除字符A
当l = 1时,在STDOUT上打印awk,当l = 0时,它不会然后perl来拯救环顾正则表达式高级技术:
perl -ne 'print if /^--AnchorA/ .. /^--Anchor(?!A)/' file.txt
检查look around(您可以用字符串替换A
,而不仅仅是字符)
awk '
/^--AnchorA/{l=1;print;next};
l;
/^--Anchor/ && $0 !~ /^--AnchorABC/ {exit}
' file.txt
答案 1 :(得分:1)
虽然我更喜欢Gilles&#39;但我找到了一个令人讨厌的sed解决方案。 awk解决方案的可读性:
sed -ne "/^--AnchorA/{p;
:loop
n;
p;
/^--/{/^--AnchorA/\!q};
b loop}" testfile | sed '$d'
答案 2 :(得分:1)
这可能适合你(GNU sed):
sed -nr '/^--AnchorABC/{:a;N;/^--AnchorABC[^\n]*\'\''/Mba;/^--Anchor[^\n]*\'\''/M!ba;p}' file
使用GNU seds多行结束字符串\'
(此处显示为\'\''
,因为该命令是单引号)。这会使用N
收集多行,如果附加的最后一行是--AnchorABC
,则会继续追加,直到开始--Anchor
并且不继续ABC
的行然后打印该集合并重复。
N.B。 Seds M
标志允许^
和\'
分别匹配行的开头和模式空间的结尾。
答案 3 :(得分:1)
sed用于单个行上的简单替换,全部。对于其他任何你应该使用awk:
$ awk '/^--/{f=/--AnchorABC/} f' file
--AnchorABC something
--AnchorABC something else
--AnchorABC yet something else
Hey
how
are
you
可以调整它来打印终止的非匹配线,但你说having the last line deleted isn't super important
所以我没有打扰。
说明:
/^--/{f=/--AnchorABC/}
=当前行以--
开头时,如果该行包含f
和1
,则会将标记--AnchorABC
设置为0
否则。f
在最后拥有它=如果标志f
设置为1
,那么就打开
发生默认操作,即打印当前行。答案 4 :(得分:0)
这是一个awk
解决方案,
$ awk '/AnchorA/{a=1};a;/AnchorB/{exit}' file
这是一个sed
解决方案,
$ sed '/AnchorA/,/AnchorB/!d;/AnchorB/q' file
输出(两种情况):
--AnchorA something
--AnchorA something else
--AnchorA yet something else
Hey
how
are
you
--AnchorB
答案 5 :(得分:0)
awk -v search="AnchorABC" '
BEGIN{r="^[-]+"search}
$0~r{f=1}f;
/^[-]+/ && $0 !~ r{exit}
' file
测试结果:
<强> 输入: 强>
$ cat file
It
is
a
lovely
day
--AnchorABC something
--AnchorABC something else
--AnchorABC yet something else
Hey
how
are
you
--AnchorXYZ
I
am
fine
--AnchorLMN
输出:
$ awk -v search="AnchorABC" 'BEGIN{r="^[-]+"search}$0~r{f=1}f;/^[-]+/ && $0 !~ r{exit}' file
--AnchorABC something
--AnchorABC something else
--AnchorABC yet something else
Hey
how
are
you
--AnchorXYZ
答案 6 :(得分:0)
将grep
和sed
与否定前瞻混合的解决方案:
$ A=$(grep -Pnm1 '^--AnchorABC' input.file | cut -d':' -f1); B=$(tail -n +$A input.file |grep -Pnm1 '^--Anchor(?!ABC)' | cut -d':' -f1); sed -n "$A,+$((B-1)) p" input.file
--AnchorABC something
--AnchorABC something else
--AnchorABC yet something else
Hey
how
are
you
--AnchorXYZ
<强>说明:强>
$(grep -Pnm1 '^--AnchorABC' input.file | cut -d':' -f1)
找到第一次出现--AnchorABC
$(tail -n +$A input.file |grep -Pnm1 '^--Anchor(?!ABC)' | cut -d':' -f1)
从第一次出现后,您会找到多少行,直到达到符合'^--Anchor(?!ABC)'
条件的行,并且您的行号相对于第一次出现'^--AnchorABC'
sed -n "$A,+$((B-1)) p" input.file