我所获得的命令的输出在“成功”时采用以下形式:
/ > -------
ABC123
/ >
此命令可能会发出类似这样的内容(“失败”):
/ > -------
ABC123
-------
DEF456
-------
Hello (world!)
-------
(any old string, really)
/ >
或者,这(另一个“失败”):
/ > / >
对于第一个例子,我想发出:
ABC123
对于其他两个例子,我想发出空字符串。
我试过这个,这对于第三个例子非常有用:
mycmd | pcregrep -M '(?:/\s>\s{2}-{7}\n)[^\n]*(?!\n.*\n)'
但是对于它发出的前两个例子:
/ > -------
ABC123
我不知道该怎么做。我的上面的正则表达式是尝试匹配前导/ > -------
但不捕获它,然后匹配下一行只有当它没有跟着另一行以换行符结尾时。我可以使用pcregrep
之外的其他内容来解决此问题,但我无法使用awk
或sed
来表达此问题。我会使用Python,但它对我的需求来说太慢了。有什么帮助吗?
答案 0 :(得分:1)
您还可以使用awk:
BEGIN {
first_line = "";
second_line = "";
third_line = "";
ctr = 0;
}
{
if (ctr == 0 ){
first_line = $0;
} else if (ctr == 1) {
second_line = $0;
} else if (ctr == 2 ) {
third_line = $0;
}
ctr++;
}
END {
if( first_line ~ /\/ > -------/){
if( third_line ~ /\/ >/){
print second_line;
}
}
}
输出:
$ echo "/ > -------\nABC12\n ---\n/ >\n" | awk -f test.awk
$ echo "/ > -------\nABC12\n/ >\n" | awk -f test.awk
ABC12
$
我确信awk专家会畏缩,但很快就完成了工作。
答案 1 :(得分:1)
我认为以下内容可行,但如果它包含换行符,我无法使用后视表达式。
mycmd | pcregrep -M '(?<=^/ > -{7}\n).*\n(?=/ > $)'
但以下两阶段解决方案对我有用:
mycmd | pcregrep -M '^/ > -{7}\n.*\n/ > $' | pcregrep -v '^/ >'
根据OP的回答进行更新
我喜欢\ K逃脱: - )
我认为您 不 想要符合以下情况
/ > -------
/ > perhaps text here
/ >
当它包含\ n时,我能够得到负面的工作,即使它嵌入在正向前看中也是如此。
这是一个更简单的正则表达式,\K
更接近你想要的。它不允许/ >
之后的任何内容,但它仍然允许/ > -------
之前的行。
mycmd | pcregrep -Mo '^/ > -{7}\n\K(?!/ >).+(?=\n/ > $(?!\n[\s\S]))'
如果允许捕获的行以/ >
开头,则更简单:
mycmd | pcregrep -Mo '^/ > -{7}\n\K.+(?=\n/ > $(?!\n[\s\S]))'
最终更新
这是一个sed one liner,我相信会给出确切的结果,不允许任何额外的行在之前或之后。但是,它确实允许捕获以/ >
开头的行。
mycmd | sed -n '1{/^\/ > -\{7\}$/{n;/./{h;n;/^\/ > $/{${x;p}}}}}'
这是另一种sed解决方案
mycmd | sed -n '1{h;n;H;x;N;${/^\/ > -\{7\}\n..*\n\/ > $/{x;p}}}'
答案 2 :(得分:1)
我实际上通过以下pcregrep
命令获得了成功(在咬牙切齿之后):
pcregrep -Mo '^/ > {2}-{7}[\n\r]\K[^\n\r]+(?=[\n\r]/ > $)'
没有-o
标志,它包含第一行(尽管使用\K
)。 -o
使pcregrep
仅发出与模式匹配的行。事实证明,在尝试匹配换行符时,负面预测似乎不适用于多行模式。此外,在多线模式下,\s
将匹配换行符,因此我停止使用它。
我确实想要注意,这个解决方案和dbenham的解决方案都不是我想要的。我希望在第二行之后检查除了最后一行(即不包含另一个换行符)之外没有任何其他行。这些解决方案更多地假设输出结束,但必须这样做。