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
答案 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