Відповіді:
Припустимо, ви маєте розмір 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()
(або / і a 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, і не зародилася там, вона була вже в першій версії 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
опцію "Увімкнути" grep
для відповідності всьому рядку, ви піклуєтесь про всі, крім самих екзотичних випадків (наприклад, нові рядки у назві файлу).
cmp
було б краще, ніжdiff
тут?