![使用 grep 在多行上匹配两个单词之间的文本](https://linux22.com/image/152738/%E4%BD%BF%E7%94%A8%20grep%20%E5%9C%A8%E5%A4%9A%E8%A1%8C%E4%B8%8A%E5%8C%B9%E9%85%8D%E4%B8%A4%E4%B8%AA%E5%8D%95%E8%AF%8D%E4%B9%8B%E9%97%B4%E7%9A%84%E6%96%87%E6%9C%AC.png)
我知道您可以使用 a 语法,例如:
grep -oP '.word1.*?word2'
但这不适用于多行。这是一个输入示例:
user1:x:1001:1001::/home/user1home:/bin/bash
user2:x:1002:1002::/home/user2home:/bin/bash
user3:x:1003:1003::/home/user3home:/bin/bash
user4:x:1004:1004::/home/user4home:/bin/bash
我尝试使用的命令是:
grep -oP '.1002:1002.*?user4home'
我想要的输出是这样的:
1002:1002::/home/user2home:/bin/bash
user3:x:1003:1003::/home/user3home:/bin/bash
user4:x:1004:1004::/home/user4home
答案1
文件 z2 包含:
user1:x:1001:1001::/home/user1home:/bin/bash
user2:x:1002:1002::/home/user2home:/bin/bash
user3:x:1003:1003::/home/user3home:/bin/bash
user4:x:1004:1004::/home/user4home:/bin/bash first
user1:x:1001:1001::/home/user1home:/bin/bash
user2:x:1002:1002::/home/user2home:/bin/bash
user3:x:1003:1003::/home/user3home:/bin/bash
user4:x:1004:1004::/home/user4home:/bin/bash second
该实用程序cgrep
将产生:
$ cgrep -e '1002:1002' +w '/home/user4home' z2
========================================
user2:x:1002:1002::/home/user2home:/bin/bash
user3:x:1003:1003::/home/user3home:/bin/bash
user4:x:1004:1004::/home/user4home:/bin/bash first
========================================
user2:x:1002:1002::/home/user2home:/bin/bash
user3:x:1003:1003::/home/user3home:/bin/bash
user4:x:1004:1004::/home/user4home:/bin/bash second
有关cgrep
(上下文,窗口 grep):
cgrep shows context of matching patterns found in files (man)
Path : ~/executable/cgrep
Version : 8.15
Type : ELF 64-bit LSB executable, x86-64, version 1 (SYS ...)
Home : http://sourceforge.net/projects/cgrep/ (doc)
最美好的祝愿...干杯,drl
答案2
您可以使用:
grep -Pzo "1002:1002.*(\n|.)*/home/user4home" file
它将匹配以1002:1002
, Until开头的单词/home/user4home
。
答案3
您可以使用pcregrep
:
$ pcregrep -Mo "(?s)1002:1002.*/home/user4home" file
1002:1002::/home/user2home:/bin/bash
user3:x:1003:1003::/home/user3home:/bin/bash
user4:x:1004:1004::/home/user4home
修饰符(?s)
(也可以在 中使用grep -P
)进行.
包含\n
,这样就不需要显式匹配换行符。
答案4
或者将文件转换为一行然后再转换回来。
$ cat file | tr \\n \\0 | grep -oa '1002:1002.*user4home' | tr \\0 \\n
1002:1002::/home/user2home:/bin/bash
user3:x:1003:1003::/home/user3home:/bin/bash
user4:x:1004:1004::/home/user4home
您需要添加-a
togrep
将二进制文件视为文本。