Linux 检查文件的整个原始文本内容是否作为另一个文件的一部分存在

Linux 检查文件的整个原始文本内容是否作为另一个文件的一部分存在,linux,bash,unix,grep,diff,Linux,Bash,Unix,Grep,Diff,big1.txt: a b c d e big2.txt: f c g h i b small.txt: b c 在bash脚本中,如何判断small.txt的整个有序内容是否存在于另一个文件中 例如: ???small.txt big1.txt应返回true ???small.txt big2.txt应返回false请检查此项 if perl -0777 -e '$n = <>; $h = <>; exit(index($h,$n)<0)' small.tx

big1.txt:

a
b
c
d
e
big2.txt:

f
c
g
h
i
b
small.txt:

b
c
在bash脚本中,如何判断small.txt的整个有序内容是否存在于另一个文件中

例如:

???small.txt big1.txt应返回true

???small.txt big2.txt应返回false

请检查此项

if perl -0777 -e '$n = <>; $h = <>; exit(index($h,$n)<0)' small.txt big.txt
then echo small.txt is found in big.txt
fi

如果big1.txt和big2.txt不太大,可以在内存中加载。以下测试可能就足够了

# to store file content into variables
big1=$(< big1.txt)
big2=$(< big2.txt)
small=$(< small.txt)

# to run from test case
big1=$'a\nb\nc\nd\ne\n'
big2=$'f\nc\ng\nh\ni\nb\n'
small=$'b\nc\n'

if [[ ${big1} = *${small}* ]]; then echo "big1"; fi
if [[ ${big2} = *${small}* ]]; then echo "big2"; fi

有时,发现两个复杂事物“相等”的方法是做一些廉价的测试,如果它们相等,则测试结果为真;如果它们不相等,则测试结果很少为真。那些通过这个检验的人会被更仔细地检查。。。但是,只有极少数情况下,完全平等测试会很昂贵,而且不会在每次比较时触发

在这种情况下,我要做的是获取所有文件,并对它们的行进行排序。如果要查找匹配的文本,您可能希望抑制空行,并使用尾随空格分隔行,但这是您的选择。删除重复行可能很有用

现在将每个文件与所有较长的文件进行比较,以查看它是否是前缀。如果另一个文件较短,则不能作为前缀,因此我们仅根据大小消除了1/2的比较。如果排序文件A是排序文件B的前缀,那么您可以运行一个更复杂的测试,以查看实际文件A是否嵌入到文件B中,如果排序文件通过前缀测试,我怀疑这很可能是真的

有了这个想法,我们现在可以优化它了。我们不存储文本行,而是获取每个文件,对每行进行散列,给出一个散列代码文件。把这些分类。按照程序的其余部分进行操作


下一个技巧:确定我们的散列码是8位还是16位。这使它们适合您最喜欢的编程语言的角色。现在,前缀比较测试可以包括收集每个文件中字符大小的哈希代码,并将较短的哈希代码与较长的哈希代码进行字符串比较。此时,我们已将问题从读取磁盘转移到在内存中进行高效比较;我们可能无法加快速度,因为与内存计算相比,磁盘读取非常昂贵。

欢迎使用。Stack Overflow是专业和热情的程序员的问答页面。在问题中添加您自己的代码。你至少要展示你自己为解决这个问题所做的研究。。第一个成功例子是grep-vf file2 file1。第二个是for循环中的grep-q。第三个是来自,和使用。事实上,我删除了我的第一篇帖子,它没有得到很好的接受。我被要求提供一个最小的例子来测试这个东西。就这样。现在我要展示我已经做出的努力?不,我宁愿坚持一个非常简单的问题和一个简单的例子。实际上,我正在提出我希望首先找到的问题。我来这里也不是为了给我的作品打分。另一方面,我觉得我的问题对于一个有经验的用户来说应该很简单,但我开始认为可能不是。谢谢,这很有趣。关于我的问题,性能并不是一个真正的问题,但我开始怀疑这些方法更容易用现有命令实现。从技术上讲,这是最好的答案,但需要对那些不熟悉的人进行解释。或者那些不熟悉的人可以单独尝试它的不同部分,和/或阅读手册页,无论哪种方式,都能学到比填鸭式回答更详细的细节;
$ diff small big1.txt | grep -q '^<'
$ echo $?
1

$ diff small big2.txt | grep -q '^<'
$ echo $?
0

$ ! (diff small big1.txt | grep -q '^<')
$ echo $?
0

$ ! (diff small big2.txt | grep -q '^<')
$ echo $?
1

$ if diff small big1.txt | grep -q '^<'; then echo "does not exit"; else echo "does exist"; fi
does exist

$ if diff small big2.txt | grep -q '^<'; then echo "does not exit"; else echo "does exist"; fi
does not exit