Mam zrzuty bazy danych z systemu Windows na moim urządzeniu. Są to pliki tekstowe. Używam cygwina, by się przez nie przeszukiwać. Wyglądają na zwykłe pliki tekstowe; Otwieram je za pomocą edytorów tekstu, takich jak Notatnik i WordPad, i wyglądają czytelnie. Jednak gdy uruchomię na nich grep, powie binary file foo.txt matches
.
Zauważyłem, że pliki zawierają niektóre NUL
znaki ascii , które moim zdaniem są artefaktami ze zrzutu bazy danych.
Co sprawia, że grep uważa te pliki za binarne? NUL
Charakter? Czy w systemie plików jest flaga? Co muszę zmienić, aby grep wyświetlał mi dopasowania linii?
--null-data
może być przydatny, jeśliNUL
jest separatorem.Odpowiedzi:
Jeśli
NUL
gdzieś w pliku jest znak, grep uzna go za plik binarny.Może istnieć takie obejście,
cat file | tr -d '\000' | yourgrep
aby najpierw wyeliminować wszystkie wartości null, a następnie przeszukać plik.źródło
-a
/--text
, przynajmniej z GNU grep.NUL
(prawdopodobnie powoduje to, że wywołuje printf C i nadaje mu dopasowaną linię?). W takim systemie agrep cmd .sh_history
zwróci tyle pustych linii, ile jest linii pasujących do „cmd”, ponieważ każda linia sh_history ma określony format zNUL
na początku każdej linii. (ale twój komentarz „przynajmniej na temat GNU grep” prawdopodobnie się sprawdza. Nie mam go teraz pod ręką do przetestowania, ale spodziewam się, że poradzą sobie z tym dobrze)grep
na cygwin uważał za binarny, ponieważ miał długi myślnik (0x96) zamiast zwykłego myślnika / znaku minus ASCII (0x2d). Myślę, że ta odpowiedź rozwiązała problem PO, ale wygląda na to, że jest niekompletny.grep -a
pracował dla mnie:źródło
Można użyć
strings
narzędzia, aby wyodrębnić zawartość tekstu z dowolnego pliku, a następnie rury to przezgrep
coś takiego:strings file | grep pattern
.źródło
GNU grep 2.24 RTFS
Wniosek: tylko 2 i 2 przypadki:
NUL
npprintf 'a\0' | grep 'a'
błąd kodowania zgodnie z C99
mbrlen()
, np .:ponieważ
\x80
nie może być pierwszym bajtem punktu Unicode UTF-8 : UTF-8 - Opis | en.wikipedia.orgCo więcej, jak wspomniał Stéphane Chazelas. Co sprawia, że grep uważa plik za plik binarny? | Wymiana stosów Unix i Linux , kontrole są wykonywane tylko do pierwszego odczytu bufora o długości TODO.
Tylko do pierwszego odczytanego bufora
Jeśli więc wystąpi błąd NUL lub błąd kodowania w środku bardzo dużego pliku, może on zostać i tak grepowany.
Wyobrażam sobie, że dzieje się tak ze względu na wydajność.
Np .: drukuje linię:
ale to nie:
Rzeczywisty rozmiar bufora zależy od sposobu odczytu pliku. Np. Porównaj:
W przypadku
sleep
pierwszego wiersza przechodzi do grep, nawet jeśli ma on tylko 1 bajt długości, ponieważ proces przechodzi w tryb uśpienia, a drugi odczyt nie sprawdza, czy plik jest binarny.RTFS
Znajdź, gdzie jest zakodowany komunikat o błędzie Stderr:
Prowadzi nas do
/src/grep.c
:Jeśli te zmienne były dobrze nazwane, zasadniczo doszliśmy do wniosku.
encoding_error_output
Szybkie grepping dla
encoding_error_output
pokazuje, że jedyna ścieżka kodu, która może go modyfikować, przechodzibuf_has_encoding_errors
:to po prostu
man mbrlen
.nlines_first_null i nlines
Zainicjowany jako:
więc po znalezieniu wartości null
0 <= nlines_first_null
staje się prawdą.DO ZROBIENIA, kiedy może
nlines_first_null < nlines
być fałsz? Zrobiłem się leniwyPOSIX
Nie definiuje opcji binarnych grep - wyszukaj plik w poszukiwaniu wzorca | pubs.opengroup.org , a GNU grep tego nie dokumentuje, więc RTFS jest jedynym sposobem.
źródło
(printf '\n\0y') | grep y
z(printf '\n'; sleep 1; printf '\0y') | grep y
np.export LC_CTYPE='en_US.UTF-8'
co w moim przykładzie, czy coś innego? Przeczytaj Buf: niesamowity przykład, dodany do odpowiedzi. Najwyraźniej przeczytałeś źródło bardziej niż ja, przypomina mi te hakerskie koany „Student został oświecony” :-)Jeden z moich plików tekstowych został nagle uznany przez grep za binarny:
Rozwiązaniem było przekonwertowanie go za pomocą
iconv
:źródło
0xFC
szesnastkowa, więc poza zakresem grep oczekiwałby od utf8 (do0x7F
). Sprawdź za pomocą printf 'a \ x7F' | grep 'a' jak opisano powyżej Ciro.Plik
/etc/magic
lub/usr/share/misc/magic
zawiera listę sekwencjifile
używanych przez polecenie do określania typu pliku.Zauważ, że plik binarny może być rozwiązaniem zastępczym. Czasami pliki z dziwnym kodowaniem są również uważane za binarne.
grep
w systemie Linux ma kilka opcji do obsługi plików binarnych, takich jak--binary-files
lub-U / --binary
źródło
mbrlen()
. Przykład i interpretacja źródła na: unix.stackexchange.com/a/276028/32558Jeden z moich uczniów miał ten problem. Wystąpił błąd
grep
wCygwin
. Jeśli plik ma znaki inne niż Ascii,grep
iegrep
zobacz go jako plik binarny.źródło
Odpowiadając na pytanie „Co sprawia, że grep uważa plik za plik binarny?”, Możesz użyć
iconv
:W moim przypadku były hiszpańskie znaki, które poprawnie wyświetlały się w edytorach tekstu, ale grep uważał je za binarne;
iconv
wynik wskazywał na numery wierszy i kolumn tych znakówW przypadku
NUL
znakówiconv
uzna je za normalne i nie wydrukuje tego rodzaju wyników, więc ta metoda nie jest odpowiedniaźródło
Miałem ten sam problem. Widziałem
vi -b [filename]
dodane znaki. Znalazłem znaki kontrolne^@
i^M
. Następnie w vi wpisz,:1,$s/^@//g
aby usunąć^@
znaki. Powtórz to polecenie dla^M
.Ostrzeżenie: aby uzyskać „niebieskie” znaki sterujące, naciśnij Ctrl+, va następnie Ctrl+ Mlub Ctrl+ @. Następnie zapisz i wyjdź vi.
źródło