zsh: event not found: PQXY|OFEJ).)
由于这会zsh
引发错误,几乎可以肯定是因为它正在尝试处理双引号内的内容。为了保护它,您应该使用单引号,例如:
pcregrep -c '(?s)(^PQXY(?:(?!PQXY|OFEJ).)*OFEJ\n)' file.txt
我还没有pcregrep
安装,但这是一个显示问题的成绩单echo
:
pax> echo "(?s)(^PQXY(?:(?!PQXY|OFEJ).)*OFEJ)"
zsh: event not found: PQXY|OFEJ).)
pax> echo '(?s)(^PQXY(?:(?OFEJ)'
(?s)(^PQXY(?:(?OFEJ)
就解决问题而不是使用特定工具而言,在这种情况下,我实际上会选择awk
(a) 。您可以执行以下操作:
awk '/^PQXY/ { s = $0; c = 1; next}
/OFEJ$/ { if (c == 1) { print s""ORS""$0; c = 0 }; next }
/OFEJ|PQXY/ { c = 0; next }
c == 1 { s = s""ORS""$0 }' inputFile
这通过使用字符串和标志来控制收集和状态的行来工作,最初它们是空字符串和零。
然后,对于每一行:
- 如果它以 PQXY 开头,则存储该行并设置收集标志,然后转到下一个输入行。
- 否则,如果它以
OFEJ
并且您正在收集结束,则输出收集的部分并停止收集,然后转到下一个输入行。
- 否则,如果其中有任何一个字符串,则停止收集,移至下一个输入行。
- 否则,如果正在收集,则附加当前行并(隐式)移动到下一个输入行。
我已经用一些有限的测试数据对此进行了测试,它似乎工作正常。这是我用于测试的bash
脚本(b),您可以根据需要添加尽可能多的测试用例来解决您的问题。
for i in \
"PQXY 1\nabc\n2 OFEJ\n" \
"PQXY 1\nabc\n2 OFEJx\n" \
"PQXY 1\nabc\n PQXY \n2 OFEJ\n" \
"PQXY 1\nabc\n OFEJ \n2 OFEJ\n" \
"PQXY 1\nabc\ndef\nPQXY 2\n2 OFEJ\n" \
; do
echo "$i:"
printf "$i" | awk '
/^PQXY/ { s = $0; c = 1; next}
/OFEJ$/ { if (c == 1) { print s""ORS""$0; c = 0 }; next }
/OFEJ|PQXY/ { c = 0; next }
c == 1 { s = s""ORS""$0 }' | sed 's/^/ /
'
done
这是输出,因此您可以看到它的实际效果:
PQXY 1\nabc\n2 OFEJ\n:
PQXY 1
abc
2 OFEJ
PQXY 1\nabc\n2 OFEJx\n:
PQXY 1\nabc\n PQXY \n2 OFEJ\n:
PQXY 1\nabc\n OFEJ \n2 OFEJ\n:
PQXY 1\nabc\ndef\nPQXY 2\n2 OFEJ\n:
PQXY 2
2 OFEJ
(a)根据我的经验,如果您使用grep
-style regex 尝试了三件事但没有成功,那么转向更高级的工具通常会更快:-)
(b)是的,我知道它是用bash
而不是写的,zsh
但那是因为:
- 这是一个向您展示有效的测试程序
awk
,因此使用的语言无关紧要;和
- 我对
bash
tahn更满意zsh
:-)