我有两个文件,file1
和file2
。
的样本内容file1
是:
A B
C D
E F
G H
的内容file2
如下:
A B
few other lines
E F
few more other lines
A B
C D
E F
G H
few more other lines
G H
因此,我只想搜索整个file1
内容块file2
。这意味着输出应仅包含以下行:
A B
C D
E F
G H
请注意:-只有合并在一起的行才应该是输出的一部分。
我有两个文件,file1
和file2
。
的样本内容file1
是:
A B
C D
E F
G H
的内容file2
如下:
A B
few other lines
E F
few more other lines
A B
C D
E F
G H
few more other lines
G H
因此,我只想搜索整个file1
内容块file2
。这意味着输出应仅包含以下行:
A B
C D
E F
G H
请注意:-只有合并在一起的行才应该是输出的一部分。
Answers:
grep
对于多行模式,这是非常愚蠢的,但是在比较它们之前,将\n
模式和文本的所有换行符都转换为NUL字符\0
,即可解决此问题。显然也需要\0
将输出转换回\n
。
这是您的命令,假设其中file1
包含您要搜索的模式file2
:
grep -aof <(tr '\n' '\0' < file1) <(tr '\n' '\0' < file2) | tr '\0' '\n'
给定文件的示例输出:
A B
C D
E F
G H
说明:
<(tr '\n' '\0' < file1)
创建一个FIFO /命名管道/类似文件的临时对象,该对象等于file1
,但所有换行符都转换为NUL字符。<(tr '\n' '\0' < file2)
的功能相同,但适用于file2
。grep -f PATTERN_FILE INPUT_FILE
搜索从图案(多个)PATTERN_FILE
在INPUT_FILE
。-a
旗grep
使二进制文件匹配。这是必需的,因为否则它将跳过包含不可打印字符(如)的文件\0
。-o
标志grep
使其仅打印匹配的序列,而不打印找到它的整行。| tr '\0' '\n'
将左侧命令输出中的所有NUL字符转换回换行符。这里有点优雅grep
+ perl
:
$ grep -Pzo "$(perl -pe 's/\n/\\n/g' file1.txt )" file2.txt
A B
C D
E F
G H
但是,有一个大问题。如果中有尾随换行符file1
,则该格式将不正确,换句话说:A B\nC D\nE F\nG H\n\n
。
(特别感谢@terdon提供的perl部分)
正如costas所指出的,一个人可以perl -0pe 's/\n(\n+$)?/\\n/g'
代替其他perl
命令来避免在后面的换行符。file1.txt
perl -0pe 's/\n(\n+$)?/\\n/g'
。如果没有-0
的g
正则表达式变质剂是多余的。
我不太确定您想要的输出是什么,但是使用非排他性的语言很容易做到(特别是如果两个文件都可以读入内存)。这是一个Python脚本,它将告诉您有多少个匹配项。
import sys
find = open(sys.argv[1]).read()
hay = open(sys.argv[2]).read()
print("The text occurs", hay.count(find), "times")
您想打印file1
多少次匹配?用以下内容替换最后一行:
print(find * hay.count(find))
如果您确实希望执行以下操作,则可以将所有内容打包到命令行调用或别名中:
python -c 'import sys; print("The text occurs", open(sys.argv[2]).read().count(open(sys.argv[1]).read()), "times")' file1 file2
这是另一种使用python的方法(已通过进行了测试python3 3.5.2
,没有的投诉pylint3 1.5.6
):
""" Locate entire file contents contiguous in other file """
import sys
import re
from mmap import mmap, PROT_READ
def memmap(name):
""" Return memoryview of readonly mmap """
with open(name, 'rb') as file:
return memoryview(mmap(file.fileno(), 0, access=PROT_READ))
def finder(needle, haystack):
""" Return iterator """
return re.compile(re.escape(needle)).finditer(haystack)
print(tuple(finder(*(memmap(name) for name in sys.argv[1:3]))))
命令行参数via的处理sys.argv
绝对是简单的。除了传递给,您还可以对传入finder
的两个memoryview
对象的返回值做很多其他事情tuple
。SRE_Match
返回的迭代器产生的每个项目finder
都有多种方法,其采样在print
输出中进行汇总(span
例如,,告诉每个匹配项的字节范围)。
file1
而没有其他内容,请使用cat file1
。