Odpowiedzi:
Załóżmy, że masz rozmiar file1zmiennej FILE1_SZi twoja headimplementacja obsługuje -copcję (niestandardową) :
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
cmpwykonuje proste porównanie bajt-bajt i zwraca, gdy tylko zauważy różnicę, a jednocześnie diffjest narzędziem tekstowym, które korzysta ze złożonego algorytmu, aby pokazać wszystkie różnice między dwoma plikami, na których ci nie zależy.
Jeśli twój system ma cmppolecenie z GNU diffutils, to jedną z opcji jest
cmp -n 124665 file1 file2
porównać najwyżej pierwsze 124665 bajtów dwóch plików i zgłosić, jeśli się różnią - lub bardziej ogólnie
cmp -n "$(wc -c < file1)" file1 file2
$(stat -c %s file1)rozmiar w bajtach? Czy wcfaktycznie otwiera i przetwarza cały plik, aby uzyskać liczbę bajtów?
wcimplementacji zoptymalizuje tę sprawę i zrobi fstat()(lub / i a lseek(SEEK_END)), więc będzie tak wydajna, jak to możliwe. Z drugiej strony stat -cjest to specyficzne dla GNU.
cmp, możesz rozsądnie założyć, że są specyficzne dla GNU stat.
GNU cmpmoże rozwiązać problem w łatwiejszy sposób:
cmp file1 file2
Istnieją cztery możliwe wyniki (z wyjątkiem jakiegoś błędu).
Brak danych wyjściowych: pliki są identyczne.
cmp: EOF on file1: plik1 jest prefiksem pliku2.
cmp: EOF on file2: plik2 jest prefiksem pliku1.
file1 file2 differ: byte NNN, line MMM: Żaden nie jest przedrostkiem drugiego.
Niestety jest to trochę niewygodne w użyciu w skrypcie, ponieważ te przypadki nie wydają się być rozróżniane w kodzie wyjścia. Ponadto EOF on file1wiadomości trafiają do stderr, podczas gdy file1 file2 differwiadomość trafia do stdout.
Zakładam, że inne wersje cmprobią coś podobnego, ale nie sprawdziłem.
cmpnie jest poleceniem opartym tylko na GNU, ani się tam nie wywodzi, był już w pierwszej wersji Uniksa na początku lat 70. Ta -nopcja jest jednak specyficzna dla GNU.
cmp file1 file2 2>&1 | grep EOF on file1
cmpbyło to unikalne dla GNU, tylko że GNU cmpbyła jedyną wersją, której próbowałem. Dodałem zdanie w celu wyjaśnienia.
file1a drugi nazwę file12. (Lub jeszcze gorzej, co jeśli drugi plik zostanie nazwany EOF on file1?) Solidne rozwiązanie tego problemu cmpjest prawdopodobnie znacznie większym problemem niż napisanie oczywistego 5-liniowego programu w C ...
cmpjest tak ściśle ograniczona. Użycie -xopcji włącz, grepaby dopasować całą linię, zajmie się wszystkimi przypadkami oprócz najbardziej egzotycznych (np. Znaki nowej linii w nazwie pliku).
cmpbyłoby lepiej niżdifftutaj?