Ответы:
Предположим, у вас есть размер 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здесь?