# How to know if a text file is a subset of another

I am trying to find a way to predict if a text file is a subset of another..

For example:

``````foo
bar
``````

is a subset of

``````foo
bar
pluto
``````

While:

``````foo
pluto
``````

and

``````foo
bar
``````

are not one a subset of each other..

Is there a way to automatically predict this?

This check must be a cross check, and it has to return:

``````file1 subset of file2 :    True
file2 subset of file1 :    True
otherwise             :    False
``````
-
Potentially more efficient solution (if files are also ordered): github.com/barrycarter/bcapps/blob/master/… – barrycarter Dec 26 '14 at 16:03

If those file contents are called `file1`, `file2` and `file3` in order of apearance then you can do it with the following one-liner:

`````` # python -c "x=open('file1').read(); y=open('file2').read(); print x in y or y in x"
True
# python -c "x=open('file2').read(); y=open('file1').read(); print x in y or y in x"
True
# python -c "x=open('file1').read(); y=open('file3').read(); print x in y or y in x"
False
``````
-
Thanks for your answer.. +1 .. I don't know if accept my answer because yours is not unix-linux specific and my answer is a bit faster, as far as I tested it.. what do you think? – fbrundu Feb 12 '14 at 13:12
You welcome, there are of course other solutions with more unix specific tools. But this seems a good use of Python's `in` operator. – Timo Feb 12 '14 at 13:21
There is python command line wrapper to make it more unix like, with piping built in, named pyp: code.google.com/p/pyp I think it is trivial to make this solution more unix like one liner tool. – IBr Nov 14 '14 at 9:15

If f1 is a subset of f2 then f1 - f2 is an empty set. Building on that we can write an is_subset function and a function derived from it. As per Set difference between 2 text files

```

sort_files () {
f1_sorted="\$1.sorted"
f2_sorted="\$2.sorted"

if [ ! -f \$f1_sorted ]; then
cat \$1 | sort | uniq > \$f1_sorted
fi

if [ ! -f \$f2_sorted ]; then
cat \$2 | sort | uniq > \$f2_sorted
fi
}

remove_sorted_files () {
f1_sorted="\$1.sorted"
f2_sorted="\$2.sorted"
rm -f \$f1_sorted
rm -f \$f2_sorted
}

set_union () {
sort_files \$1 \$2
cat "\$1.sorted" "\$2.sorted" | sort | uniq
remove_sorted_files \$1 \$2
}

set_diff () {
sort_files \$1 \$2
cat "\$1.sorted" "\$2.sorted" "\$2.sorted" | sort | uniq -u
remove_sorted_files \$1 \$2
}

rset_diff () {
sort_files \$1 \$2
cat "\$1.sorted" "\$2.sorted" "\$1.sorted" | sort | uniq -u
remove_sorted_files \$1 \$2
}

is_subset () {
sort_files \$1 \$2
output=\$(set_diff \$1 \$2)
remove_sorted_files \$1 \$2

if [ -z \$output ]; then
return 0
else
return 1
fi

}

```
-

I found a solution thanks to this question

Basically I am testing two files `a.txt` and `b.txt` with this script:

``````#!/bin/bash

first_cmp=\$(diff --unchanged-line-format= --old-line-format= --new-line-format='%L' "\$1" "\$2" | wc -l)
second_cmp=\$(diff --unchanged-line-format= --old-line-format= --new-line-format='%L' "\$2" "\$1" | wc -l)

if [ "\$first_cmp" -eq "0" -o "\$second_cmp" -eq "0" ]
then
echo "Subset"
exit 0
else
echo "Not subset"
exit 1
fi
``````

If one is subset of the other the script return `0` for `True` otherwise `1`.

-