2013-01-03 16 views
20

Generuję pliki danych binarnych, które są po prostu serią rekordów połączonych ze sobą. Każdy rekord składa się z nagłówka (binarnego), a następnie danych binarnych. W nagłówku binarnym znajduje się ciąg znaków ASCII o długości 80 znaków. Gdzieś po drodze mój proces zapisywania plików został trochę sponiewierany i próbuję rozwiązać ten problem, sprawdzając, jak długo każdy z tych rekordów faktycznie jest."grep" przesunięcie łańcucha ascii z pliku binarnego

This wydaje się być bardzo powiązany, ale nie rozumiem perla, więc nie byłem w stanie uzyskać akceptowanej odpowiedzi tam do pracy. Druga odpowiedź wskazuje na bgrep, którą skompilowałem, ale chce, żebym go podał w postaci ciągu szesnastkowego, a ja wolałbym mieć narzędzie, w którym mogę nadać mu ciąg ascii, a znajdzie go w danych binarnych, wydrukuj ciąg znaków i przesunięcie bajtów w miejscu, w którym został znaleziony.

Innymi słowy, szukam jakiegoś narzędzia, które działa tak:

tool foobar filename 

lub

tool foobar < filename 

a jego produkcja jest mniej więcej tak:

foobar:10 
foobar:410 
foobar:810 
foobar:1210 
... 

na przykład ciąg, który pasował i przesunięcie bajtowe w pliku, w którym rozpoczęło się dopasowanie. W tym przykładowym przypadku mogę wywnioskować, że każdy rekord ma długość 400 bajtów.

Inne ograniczenia:

  • Możliwość wyszukiwania przez regex jest cool, ale nie trzeba go do tego problemu
  • Moje pliki binarne są duże (3.5GB), więc chciałbym w miarę możliwości unikaj czytania całego pliku w pamięci.
+0

argv! Nie wiem, w którym momencie moje opanowanie gramatyki angielskiej ześlizgnęło się w błoto. Dzięki za naprawienie tego dla mnie @Kevin – mgilson

Odpowiedz

23

Można użyć strings na to:

strings -a -t x filename | grep foobar 

Testowane z binutils GNU.

Na przykład, gdy w /bin/ls ma --help wystąpić:

strings -a -t x /bin/ls | grep -- --help 

wyjściowa:

14938 Try `%s --help' for more information. 
162f0  --help  display this help and exit 
+3

Skończyło się na użyciu 'strings -a -t d filename | grep foobar', aby zapisać wynik w postaci dziesiętnej zamiast heksadecymalnej. W przeciwnym razie świetna odpowiedź, która wygląda na to, że będzie działać z różnymi smakami 'grep'. – mgilson

22
grep --byte-offset --only-matching --text foobar filename 

W --byte-offset opcja drukuje przesunięcie każdej linii.

Opcja --only-matching powoduje, że drukowane są przesunięcia dla każdej dopasowanej instancji zamiast każdej pasującej linii.

Opcja --text powoduje, że grep traktuje plik binarny jako plik tekstowy.

można skrócić go:

grep -oba foobar filename 

Działa w wersji GNU grep, który pochodzi z Linux domyślnie. Nie zadziała w grep BSD (domyślnie jest to Mac).

+0

Próbowałem tego, wszystko to mówi: "Binarna nazwa pliku pasuje do pliku". Moim systemem jest Ubuntu Linux, a 'grep --version' daje:" GNU grep 2.5.2 " – mgilson

+1

Spróbuj dodać opcję' -a', aby traktować pliki binarne jako tekst –

+0

Pozdrawiam, który działa (z '-a'). +1. – mgilson

0

Chciałem zrobić to samo. Chociaż struny | Grep pracował, znalazłem gsar był bardzo narzędziem, którego potrzebowałem.

http://tjaberg.com/

Wyjście wygląda następująco:

>gsar.exe -bic -sfoobar filename.bin 
filename.bin: 0x34b5: AAA foobar BBB 
filename.bin: 0x56a0: foobar DDD 
filename.bin: 2 matches found 
Powiązane problemy