Проверьте, что весь необработанный текстовый файл существует как часть другого файла. - PullRequest
0 голосов
/ 20 января 2019

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 голосов
/ 21 января 2019
$ 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
0 голосов
/ 20 января 2019

Если 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
0 голосов
/ 21 января 2019

Иногда способ обнаружить, что две сложные вещи «равны», состоит в том, чтобы сделать какой-нибудь дешевый тест, который верен, если они равны, и редко верен, если это не так.Те, кто проходит этот уличный тест, затем проверяются более тщательно ... но редко, поэтому тест на полное равенство может быть дорогим и при этом не запускаться при каждом сравнении.

Что бы я сделал в этом случае, это взять всефайлы и сортировать их строки.(Возможно, вы захотите подавить пустые строки, если вы ищете соответствующий текст, и лишить линии конечных пробелов, но это ваш выбор).Вероятно, полезно удалить дубликаты строк.

Теперь сравните каждый файл со всеми более длинными файлами, чтобы увидеть, является ли он префиксом.(Не может быть префиксом, если другой файл короче, поэтому мы избавляемся от 1/2 сравнения только на основе размеров).Если отсортированный файл A является префиксом отсортированного файла B, то вы можете выполнить более сложный тест, чтобы увидеть, вставлен ли настоящий файл A в файл B (что, как я подозреваю, будет с большой вероятностью истинным, если отсортированные файлы пройдут тест префикса).).

Имея эту идею, теперь мы можем ее оптимизировать.Вместо того, чтобы хранить строки текста, мы берем каждый файл и хэшируем каждую строку, давая файл хеш-кодов.Сортируй это.Выполните оставшуюся часть процедуры.

Следующий прием: решите, что наши хеш-коды имеют размер 8 или 16 бит.Это позволяет им соответствовать характеру вашего любимого языка программирования.Теперь ваш тест сравнения префиксов может состоять из сбора хеш-кодов размером в символ для каждого файла и сравнения строк более коротких и более длинных.На данный момент мы переместили проблему с чтения диска на эффективное сравнение в памяти;мы, вероятно, не сможем ускорить его, потому что чтение с диска очень дорого по сравнению с вычислениями в памяти.

0 голосов
/ 20 января 2019

отметьте это, пожалуйста

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
...