Câu trả lời:
Giả sử bạn có kích thước của file1
biến FILE1_SZ
và head
việc triển khai của bạn hỗ trợ -c
tùy chọn (không chuẩn) :
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
so sánh byte với byte đơn giản và trả về ngay khi tìm thấy sự khác biệt, trong khi đó diff
là một tiện ích văn bản sẽ sử dụng thuật toán phức tạp để hiển thị cho bạn tất cả sự khác biệt giữa hai tệp mà bạn không quan tâm.
Nếu hệ thống của bạn có cmp
lệnh từ GNU diffutils
, thì một tùy chọn là
cmp -n 124665 file1 file2
để so sánh tối đa 124665 byte đầu tiên của hai tệp và báo cáo nếu chúng khác nhau - hoặc, nói chung hơn
cmp -n "$(wc -c < file1)" file1 file2
$(stat -c %s file1)
kích thước theo byte? Có wc
thực sự mở và xử lý toàn bộ tập tin để có được số byte?
wc
triển khai sẽ tối ưu hóa trường hợp đó và thực hiện fstat()
(hoặc / và a lseek(SEEK_END)
) vì vậy sẽ hiệu quả như nó có. Mặt khác, đó stat -c
là GNU cụ thể.
cmp
, bạn có thể giả định hợp lý GNU stat
.
GNU cmp
có thể giải quyết vấn đề một cách dễ dàng hơn:
cmp file1 file2
Có bốn đầu ra có thể (chặn một số loại lỗi).
Không có đầu ra: các tập tin là giống hệt nhau.
cmp: EOF on file1
: file1 là tiền tố của file2.
cmp: EOF on file2
: file2 là tiền tố của file1.
file1 file2 differ: byte NNN, line MMM
: Không phải là tiền tố của người khác.
Thật không may, điều này hơi khó sử dụng trong một tập lệnh, vì những trường hợp này dường như không được phân biệt trong mã thoát. Hơn nữa, các EOF on file1
tin nhắn đi đến stderr, trong khi file1 file2 differ
tin nhắn đi đến thiết bị xuất chuẩn.
Tôi đoán rằng các phiên bản khác của cmp
một cái gì đó tương tự, nhưng tôi đã không kiểm tra.
cmp
không phải là lệnh chỉ dành cho GNU và cũng không bắt nguồn từ đó, nó đã có trong phiên bản đầu tiên của Unix vào đầu những năm 70. Các -n
tùy chọn là GNU cụ thể mặc dù.
cmp file1 file2 2>&1 | grep EOF on file1
cmp
là duy nhất với GNU, chỉ có điều GNU cmp
là phiên bản duy nhất tôi đã thử. Tôi thêm một câu để làm rõ.
file1
và tệp còn lại được đặt tên file12
. (Hoặc tệ hơn nữa, nếu tập tin thứ hai được đặt tên EOF on file1
thì sao?) Việc giải quyết việc sử dụng mạnh mẽ cmp
này có lẽ rắc rối hơn nhiều so với việc viết chương trình 5 dòng rõ ràng trong C ...
cmp
rất hạn chế. Sử dụng -x
tùy chọn trên grep
để khớp với toàn bộ dòng sẽ xử lý tất cả các trường hợp ngoại trừ trường hợp kỳ lạ nhất (ví dụ: dòng mới trong tên tệp).
cmp
sẽ tốt hơndiff
ở đây không?