Найдите значение HEX в файле и введите следующее значение

У меня есть файл размером 2 ГБ в необработанном формате. Я хочу найти все появление определенного шестнадцатеричного значения "355A3C2F74696D653E" И собрать следующие 28 символов.

Пример: 355A3C2F74696D653E323031312D30342D32365431343A34373A30322D31343A34373A3135

В этом случае мне нужен результат: "323031312D30342D32365431343A34373A30322D31343A34373A3135" или лучше: 2011-04-26T14:47:02-14:47:15

Я пробовал с

xxd -u InputFile | grep '355A3C2F74696D653E' | cut -c 1-28 > OutputFile.txt

а также

xxd -u -ps -c 4000000 InputFile | grep '355A3C2F74696D653E' | cut -b 1-28 > OutputFile.txt

Но я не могу заставить его работать.

Кто-нибудь может мне намекнуть?


person hdk    schedule 30.04.2015    source источник
comment
но ваш ожидаемый результат имеет символы более 28.   -  person Avinash Raj    schedule 30.04.2015
comment
Каким образом ваши попытки потерпели неудачу? В чем разница между их результатом и желаемым результатом?   -  person Yunnosch    schedule 10.08.2017


Ответы (3)


Поскольку вы используете xxd, мне кажется, что вы хотите искать в файле, как если бы это были двоичные данные. Я бы рекомендовал использовать для этого более мощный язык программирования; инструменты оболочки Unix предполагают, что есть окончания строк и что текст в основном является 7-битным ASCII. Рассмотрите возможность использования Python:

#!/usr/bin/python
import mmap
fd = open("file_to_search", "rb")
needle = "\x35\x5A\x3C\x2F\x74\x69\x6D\x65\x3E"
haystack = mmap.mmap(fd.fileno(), length = 0, access = mmap.ACCESS_READ)
i = haystack.find(needle)
while i >= 0:
    i += len(needle)
    print (haystack[i : i + 28])
    i = haystack.find(needle, i)
person Jack Whitham    schedule 30.04.2015
comment
Привет, я не настолько опытен в python, только попробовал небольшой скрипт, но предполагая, что мне просто нужно скопировать / вставить командные строки в пустой документ блокнота, сохраните его, например, как Needle и запустите его, набрав bash Needle в терминале ... ?? Когда я это делаю, он говорит: Игла: строка 2: импорт: команда не найдена Игла: строка 3: синтаксическая ошибка рядом с неожиданным токеном (' Needle: line 3: fd = open (InputFileName, rb) «Я поместил сценарий в ту же папку, что и InputFile. Что я делаю неправильно? С уважением, HDK - person hdk; 01.05.2015
comment
Он не запускается интерпретатором Python. Сохраните файл как script.py, а затем запустите python script.py в Bash. - person Jack Whitham; 01.05.2015
comment
Привет снова, теперь это работает :-) Большое спасибо. Я также попытался записать вывод в файл с помощью: writeFile = open ('Time.txt', 'w') и в цикле while: writeFile.write (haystack [i: i + 28]). Он работает нормально, но мне нужна одна строка на итерацию, а на выходе получается одна длинная строка текста. Я пробовал писать строки и строки письма, но это не меняет вывода. - person hdk; 01.05.2015
comment
Используйте writeFile.write("\n"), чтобы вставить новую строку. - person Jack Whitham; 01.05.2015
comment
Привет, Джек, спасибо, теперь все работает отлично. Я новичок в stackoverflow, могу ли я отметить ваш ответ как полезный или поставить вам палец вверх ... ?? С уважением, hdk. - person hdk; 01.05.2015
comment
Привет, Джек помог мне в прошлом году со сценарием Python. Это было очень полезно. Теперь я хочу использовать его снова, но на этот раз вывод должен быть в шестнадцатеричном формате, и было бы очень хорошо иметь смещение, если бы «игла» находилась в стоге сена. Это возможно? - person hdk; 13.12.2016

Если ваш grep поддерживает параметр -P, вы можете просто использовать команду ниже.

$ echo '355A3C2F74696D653E323031312D30342D32365431343A34373A30322D31343A34373A3135' | grep -oP '355A3C2F74696D653E\K.{28}'
323031312D30342D32365431343A

Для 56 символов

$ echo '355A3C2F74696D653E323031312D30342D32365431343A34373A30322D31343A34373A3135' | grep -oP '355A3C2F74696D653E\K.{56}'
323031312D30342D32365431343A34373A30322D31343A34373A3135
person Avinash Raj    schedule 30.04.2015
comment
Привет, результат, который я получил с помощью опубликованной мной команды, очень похож на тот, который вы предлагаете, но он дает результат, который я не могу использовать, смесь HEX и простого текста: 5432 303A 3237 2011-04-2 5432 303A e ›2011-04-26T2 5432 303A 3239 2011-04-2 5432 303A e› 2011-04-26T2 5432 303A 3333 2011-04-2 5432 303A e ›2011-04-26T2 5432 303A 3530 2011-04-2 Вот 7 строк (я не знаю, как сдвигать строку ...: - /) - person hdk; 30.04.2015
comment
Примите ответ и задайте это как новый вопрос. - person Avinash Raj; 01.05.2015

Зачем сначала конвертировать в шестнадцатеричный формат? Посмотрите, подходит ли вам этот сценарий awk. Он ищет строку, по которой вы хотите сопоставить, затем печатает следующие 28 символов. Специальные символы в шаблоне экранируются обратной косой чертой.

Адаптировано из этого сообщения: Символы Grep до и после совпадения?

Я добавил несколько пустых строк для удобства чтения.

VirtualBox:~$ cat data.dat

Thisis a test of somerandom characters before thestringI want5Z</time>2011-04-26T14:47:02-14:47:15plus somemoredata

VirtualBox:~$ cat test.sh

awk '/5Z\<\/time\>/ {
  match($0, /5Z\<\/time\>/); print substr($0, RSTART + 9, 28);
}' data.dat

VirtualBox:~$ ./test.sh

2011-04-26T14:47:02-14:47:15

VirtualBox:~$ 

РЕДАКТИРОВАТЬ: Я только что кое-что понял. Регулярное выражение необходимо настроить, чтобы оно было не жадным и т. Д., А между этим и awk необходимо настроить обработку нескольких вхождений по мере необходимости. Возможно, кто-то из тех, кто больше знаком с awk, внесет свои улучшения, так как я очень ржавый. В любом случае подход к рассмотрению.

person Gary_W    schedule 30.04.2015