In che modo grep decide che un file è binario?


8

Ho un grande file di testo utf-8 con cui cerco frequentemente grep. Di recente ha grepiniziato a segnalare che si trattava di un file binario. Posso continuare a cercarlo con grep -a, ma mi chiedevo quale modifica ha fatto decidere che il file era ora binario.

Ne ho una copia dello scorso mese in cui il file non viene più rilevato come binario, ma non è pratico per diffloro poiché differiscono su> 20.000 righe.

file identifica il mio file come

Testo inglese Unicode UTF-8, con linee molto lunghe

Come posso trovare i caratteri / linee / ecc. nel mio file che stanno innescando questa modifica?


La domanda simile, non duplicata 19907, copre la possibilità di NUL, ma grep -Pc '[\x00-\x1F]'afferma che non ho NUL o altri capitani di controllo ANSI.


Vorrei provare questo in questo ordine: 1. Eseguilo con strace / ltrace per verificare quali input causano quel messaggio 'binario' 2. Controlla la fonte di grep e
leggila

@muru: sto usando gnu grep, ma se hai la risposta per qualche altra versione sarei anche interessato.
Charles,

Dispari. Ho un file che so contiene ae nulalcuni Escs. Ho provato a prenderlo per loro. Sono riuscito a trovare escs ( \x1B), ma nulnon è mai stato visualizzato. Il test sopra riportato mostrava 1, per la riga contenente Escs, ma nulla per qualsiasi intervallo che non contenesse \x1B. Non mi fiderei di quel test. Prova grep -zc .invece (dovrebbe essere uno in più rispetto al numero di nuls nel tuo file). (Inoltre, potresti stare meglio usando [[:cntrl:]].)
muru

Prova anche sed -z 's/.*\(....\)$/\1/' foo | od -ca vedere alcuni caratteri prima del NUL(se ce n'è uno), il che potrebbe portare al problema.
muru,

@muru: Il mio sednon dispone di -zun'opzione: sed: invalid option -- 'z'.
Charles,

Risposte:


2

Sembra essere la presenza del carattere null nel file. (Visualizzato ^ @ di solito) Ho inserito vari caratteri di controllo in un file di testo (come delete, ^ ?, per esempio), e solo il carattere null ha fatto sì che grep lo considerasse un binario. Questo è stato testato solo per grep. I comandi less e diff, ad esempio, possono avere metodi diversi. I personaggi di controllo in generale non appaiono se non nei binari. Le eccezioni sono i caratteri degli spazi bianchi: newline (^ M), tab (^ I), formfeed (^ L), tab verticale (^ K) e return (^ J).

Tuttavia, i caratteri stranieri, come le lettere arabe o cinesi, non sono ascii standard e forse potrebbero essere confusi con i caratteri di controllo. Forse è per questo che è solo il carattere null.

Puoi provarlo tu stesso inserendo i caratteri di controllo in un file di testo usando l'editor di testo vim. Basta andare in modalità di inserimento, premere control-v, quindi il carattere di controllo.


2

Una tipica implementazione moderna di grep dovrebbe dichiarare un file "binario" solo se ci sono nul byte all'interno. Tutto il resto dovrebbe essere OK.

Non posso parlare per l'implementazione grep che usi ...


1

Un errore di codifica secondo mbrlen () fa anche in modo che GNU grep 2.24 lo consideri binario

Per esempio:

export LC_CTYPE='en_US.UTF-8'
printf 'a\x80' | grep 'a'

perché \x80non può essere il primo byte di un punto Unicode UTF-8: https://en.wikipedia.org/wiki/UTF-8#Description

Questa è l'unica altra possibilità oltre NUL.

grepInterpretazione del codice sorgente GNU che porta a questa conclusione: Cosa rende grep un file binario?

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.