Come verificare se file1 è un prefisso di file2?


13

Ho due file con dimensioni 124665 e 124858 in byte e voglio verificare se file1 è un prefisso di file2 oppure no.

Risposte:


11

Supponendo che tu abbia la dimensione di file1nella variabile FILE1_SZe che l' headimplementazione supporti l' -copzione (non standard) :

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

@ StéphaneChazelas Puoi per favore spiegare perché cmpsarebbe meglio di diffqui?
Joseph R.

7
Perché cmpfa un semplice confronto da byte a byte e ritorna non appena trova una differenza, mentre diffè un'utilità di testo che utilizzerà un algoritmo complesso per mostrarti tutte le differenze tra i due file che non ti interessano.
Stéphane Chazelas,

12

Se il tuo sistema ha il cmpcomando da GNU diffutils, allora un'opzione è

cmp -n 124665 file1 file2

per confrontare al massimo i primi 124665 byte dei due file e segnalare se differiscono - o, più in generale

cmp -n "$(wc -c < file1)" file1 file2

@StephaneChazelas Sto indovinando me stesso qui, ma sarebbe meglio suggerire $(stat -c %s file1)per la dimensione in byte? In wcrealtà apre ed elabora l'intero file per ottenere il conteggio dei byte?
Steeldriver,

2
no, la maggior parte delle wcimplementazioni ottimizzerà quel caso e farà un fstat()(o / e a lseek(SEEK_END)), quindi sarà efficiente come si arriva. D'altra parte, questo stat -cè specifico per GNU.
Stéphane Chazelas,

1
Sebbene se hai bisogno di specifiche GNU cmp, potresti ragionevolmente supporre specifiche GNU stat.
Barmar,

3

GNU cmppuò risolvere il problema in modo più semplice:

cmp file1 file2

Esistono quattro possibili uscite (salvo una sorta di errore).

  • Nessun output: i file sono identici.

  • cmp: EOF on file1: file1 è un prefisso di file2.

  • cmp: EOF on file2: file2 è un prefisso di file1.

  • file1 file2 differ: byte NNN, line MMM: Né è un prefisso dell'altro.

Sfortunatamente questo è un po 'imbarazzante da usare in uno script, dal momento che questi casi non sembrano essere distinti nel codice di uscita. Inoltre, i EOF on file1messaggi vanno a stderr, mentre il file1 file2 differmessaggio va a stdout.

Presumo che altre versioni di cmpfare qualcosa di simile, ma non ho verificato.


1
cmpnon è un comando solo GNU né è nato lì, era già nella prima versione di Unix nei primi anni '70. L' -nopzione è specifica per GNU però.
Stéphane Chazelas,

Si potrebbe farecmp file1 file2 2>&1 | grep EOF on file1
David Z

@ StéphaneChazelas: è vero. Non intendevo implicare che cmpfosse unico per GNU, solo che GNU cmpera l'unica versione che ho provato. Ho aggiunto una frase per chiarire.
Nate Eldredge,

@DavidZ: Sì, potresti, ma diventa un po 'meno robusto. Immagina di provare a farlo con due file forniti dall'utente e uno di questi è chiamato file1e l'altro è chiamato file12. (O peggio ancora, cosa succede se il secondo file viene chiamato EOF on file1?) Risolvere questo utilizzo in modo efficace cmpè probabilmente molto più problematico che scrivere l'evidente programma a 5 righe in C ...
Nate Eldredge,

Tuttavia, potrebbero esserci contesti in cui un programma C non è pratico. E non è così difficile renderlo abbastanza robusto, perché l'output di cmpè così strettamente limitato. L'uso -xdell'opzione on grepper abbinare l'intera riga si occuperà di tutti tranne i casi più esotici (ad es. Newline nel nome del file).
David Z,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.