通过仅对第一个模式执行完全匹配来提取两个模式之间的线



我正在尝试从位于两行之间的大文件行中提取,每行都由某种模式标记,假设模式 1 和模式 2。我的代码 :

awk "/pattern1/{flag=1;next}/pattern2/{flag=0}flag" filename

验证一行中是否存在"pattern1",并从该行开始打印,直到找到字符串"pattern2"所在的后续行。

我想做的是将字符串"pattern1"与awk开始打印的行完全匹配,并通过验证行中是否存在"pattern2"来检测awk将停止打印的行(没有完全匹配)。所以基本上,我想对第一个模式进行精确匹配,并为第二个模式保留上述命令的匹配行为。

awk内置了这样的功能:

$ cat data 
abcd
pattern1
xyz
pattern2
abcde
$ awk '/pattern1/,/pattern2/' data
pattern1
xyz
pattern2

sed也有:

$ sed -n '/pattern1/,/pattern2/p' data
pattern1
xyz
pattern2

编辑:为此,您必须使用某种锚点,无论是单词边界y gawk,还是像这样开始和结束锚点:

$ cat data 
abcd
pattern1 234
pattern1
xyz
pattern2
abcde
$ awk '/^pattern1$/,/pattern2/' data 
pattern1
xyz
pattern2

如果您想打印或不打印pattern1/pattern2行的组合,您可以使用这些:

$ awk '/^pattern1$/{flag=1} /pattern2/{flag=0}flag' data 
pattern1
xyz
$ awk '/^pattern1$/{flag=1;next} /pattern2/{flag=0}flag' data 
xyz
$ awk '/^pattern1$/{flag=1;next;} /pattern2/{flag=0;print}flag' data 
xyz
pattern2

这是与问题中的建议一致的另一个答案:

awk 'BEGIN{flag=0} /^pattern1$/{flag=1;print;next} /pattern2/{flag=0;next} {if (flag == 1) {print}}'

第一种模式必须与整行完全匹配(使用 ^ 和 $),而第二种模式可以出现在线条内的任何位置。

编辑:此版本确实打印了出现模式1的行。 如果您不想打印它们,请将"flag=1;print;next"替换为"flag=1;next"。

如果没有示例输入/输出,这是一个猜测,但这可能是您想要的:

awk '/pattern2/{flag=0} flag; $0=="pattern1"{flag=1}' filename

可以写成更有意义的是:

awk '/end_regexp/{found=0} found; $0=="start_string"{found=1}' filename

(Nbd,但命名标志flag与命名函数function一样有用!

我实际上认为这可能是您真正应该使用的,但是idk:

awk 'index($0,"end_string"){found=0} found; $0=="start_string"{found=1}' filename

另请参阅 https://stackoverflow.com/a/18409469/1745001,了解使用 awk 查找文本的更多方法。

awk 'BEGIN{flag=0} /^pattern1$/{flag=1;print;next} /pattern2/{if (flag == 1) {print}; flag=0;} {if (flag == 1) {print}}' filename

这样就可以避免打印双重"图案2":

me:~$ awk 'BEGIN{flag=0} /^pattern1$/{flag=1;print;next} /pattern2/{if (flag == 1) {print}; flag=0;} {if (flag == 1) {print}}' a
pattern1
xyz
as pattern2 sd
me:~$ cat a
abcd
pattern1 23
pattern1
xyz
as pattern2 sd
abcde
pattern2

相关内容

  • 没有找到相关文章

最新更新