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

时间:2019-01-20 18:05:51

标签: 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

4 个答案:

答案 0 :(得分:1)

如果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 :(得分:1)

有时候发现两个复杂的事物是“相等的”的方法是进行一些廉价的测试,如果它们相等则为真,否则就很少为真。然后,对通过了这种循序渐进式测试的人进行更仔细的检查……但是很少,因此完全相等的测试可能会很昂贵,但不会在每次比较时都被触发。

在这种情况下,我要做的就是获取所有文件,并对它们的行进行排序。 (如果您要查找匹配的文本,则可能要禁止显示空白行,并在行末尾添加空白行,但这是您的选择)。删除重复行可能有用。

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

有了这个想法,我们现在可以对其进行优化。代替存储文本行,我们获取每个文件,并对每一行进行哈希处理,从而得到一个哈希码文件。排序这些。请按照其余步骤进行操作。

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

答案 2 :(得分:1)

$ 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

答案 3 :(得分:0)

请选中此

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