Ответы:
Предположим, у вас есть размер file1
переменной FILE1_SZ
и ваша head
реализация поддерживает (нестандартную) -c
опцию:
if head -c "$FILE1_SZ" file2 | cmp -s - file1; then
echo "file1 is a prefix of file2"
else
echo "file1 is not a prefix of file2"
fi
cmp
что выполняет простое байтовое сравнение и возвращает, как только обнаружит разницу, а diff
текстовая утилита собирается использовать сложный алгоритм, чтобы показать вам все различия между двумя файлами, которые вас не интересуют.
Если ваша система имеет cmp
команду из GNU diffutils
, то одна из опций
cmp -n 124665 file1 file2
сравнить не более первых 124665 байтов двух файлов и сообщить, отличаются ли они - или, в более общем случае,
cmp -n "$(wc -c < file1)" file1 file2
$(stat -c %s file1)
размер в байтах? На wc
самом деле открыть и обработать весь файл, чтобы получить количество байтов?
wc
реализаций оптимизирует этот случай и выполнит fstat()
(или / и lseek(SEEK_END)
), поэтому будет настолько эффективным, насколько это возможно. С другой стороны, это stat -c
специфично для GNU.
cmp
, вы можете разумно предположить специфичную для GNU stat
.
GNU cmp
может решить проблему проще:
cmp file1 file2
Есть четыре возможных выхода (исключая какую-то ошибку).
Нет вывода: файлы идентичны.
cmp: EOF on file1
: file1 является префиксом file2.
cmp: EOF on file2
: file2 является префиксом file1.
file1 file2 differ: byte NNN, line MMM
: Ни один не является префиксом другого.
К сожалению, это немного неудобно для использования в скрипте, так как эти случаи, кажется, не различаются в коде выхода. Более того, EOF on file1
сообщения отправляются в stderr, а file1 file2 differ
сообщения - в stdout.
Я предполагаю, что другие версии cmp
делают что-то подобное, но я не проверял.
cmp
это не команда GNU-only и она не возникла там, она была уже в первой версии Unix в начале 70-х годов. Эта -n
опция специфична для GNU.
cmp file1 file2 2>&1 | grep EOF on file1
cmp
это уникально для GNU, просто GNU cmp
была единственной версией, которую я пробовал. Я добавил предложение, чтобы уточнить.
file1
а другой назван file12
. (Или, что еще хуже, что, если второй файл будет назван EOF on file1
?) Решить это с помощью надежного использования cmp
, вероятно, гораздо сложнее, чем написать очевидную 5-строчную программу на C ...
cmp
очень сильно ограничены. Использование -x
опции on, grep
чтобы соответствовать всей строке, позаботится обо всех, кроме самых экзотических случаях (например, новые строки в имени файла).
cmp
было бы лучше, чемdiff
здесь?