Odpowiedzi:
Załóżmy, że masz rozmiar file1
zmiennej FILE1_SZ
i twoja head
implementacja obsługuje -c
opcję (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
cmp
wykonuje proste porównanie bajt-bajt i zwraca, gdy tylko zauważy różnicę, a jednocześnie diff
jest 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 cmp
polecenie 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 wc
faktycznie otwiera i przetwarza cały plik, aby uzyskać liczbę bajtów?
wc
implementacji 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 -c
jest to specyficzne dla GNU.
cmp
, możesz rozsądnie założyć, że są specyficzne dla GNU stat
.
GNU cmp
moż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 file1
wiadomości trafiają do stderr, podczas gdy file1 file2 differ
wiadomość trafia do stdout.
Zakładam, że inne wersje cmp
robią coś podobnego, ale nie sprawdziłem.
cmp
nie jest poleceniem opartym tylko na GNU, ani się tam nie wywodzi, był już w pierwszej wersji Uniksa na początku lat 70. Ta -n
opcja jest jednak specyficzna dla GNU.
cmp file1 file2 2>&1 | grep EOF on file1
cmp
było to unikalne dla GNU, tylko że GNU cmp
była jedyną wersją, której próbowałem. Dodałem zdanie w celu wyjaśnienia.
file1
a drugi nazwę file12
. (Lub jeszcze gorzej, co jeśli drugi plik zostanie nazwany EOF on file1
?) Solidne rozwiązanie tego problemu cmp
jest prawdopodobnie znacznie większym problemem niż napisanie oczywistego 5-liniowego programu w C ...
cmp
jest tak ściśle ograniczona. Użycie -x
opcji włącz, grep
aby dopasować całą linię, zajmie się wszystkimi przypadkami oprócz najbardziej egzotycznych (np. Znaki nowej linii w nazwie pliku).
cmp
byłoby lepiej niżdiff
tutaj?