-1

Есть ли простая командная строка unix, которую я могу ввести, которая позволяет мне выделять, скажем, 512 байт с каждой стороны поискового запроса, даже если в очень большом текстовом файле есть только одна "строка"?

Хорошо, это должно быть легко.

Знаменитые последние слова.

Я не очень знаком с grep, но кажется, что он в основном используется для фильтрации строк во входных данных, которые содержат условия поиска.

У меня есть очень большой файл JSON, который я скачал, и я хочу найти определенный термин.

перед тем, как щелкнуть ссылку - она занимает более 244 МБ, поэтому будьте осторожны - она отправлена с интернет-машины обратной связи и содержит списки zip-файлов архивных фотографий. Я пытаюсь найти мой.

Их веб-интерфейс поврежден, поэтому я нашел файл json, который они здесь публикуют - он последний в списке.

когда я grep ищет мое имя пользователя, он находит его, но продолжает выводить эту строку на консоль. проблема в том, что длина строки составляет 244 МБ, и это единственная строка в файле.

Я пытался использовать меньше, но не мог заставить это сделать много - это очень медленно, и, кажется, имеет ту же проблему.

Есть ли простая командная строка Unix, которую я могу ввести, которая позволяет мне выделить, скажем, 512 байт по обе стороны от условия поиска?

3 ответа3

2

Поскольку у вас уже есть загруженный файл json, вы можете выполнить некоторые манипуляции с ним, чтобы упростить поиск.

Я скачал первые несколько сотен байтов файла json, и я вижу, что файл выглядит так:

["entry1","date1","file1.gz",int1,"string1","string1",int1],["entry2","date2","file2.gz",int2,"string2","string2",int2],[...

Похоже, что каждая запись находится в отдельном массиве json, разделенном символами ],[ . Вы можете использовать sed чтобы заменить эти символы переводом строки.

sed 's_\],\[_\]\n\[_g' json_file > json_file_with_breaks

Эта команда будет вставлять разрыв строки после каждой записи, поэтому вы получите одну запись на строку:

[... entry1 ...],
[... entry2 ...],
...

Вывод будет сохранен в новый файл, json_file_with_breaks . Я рекомендую это, потому что, если вам нужно сделать несколько поисков, запуск grep для нового файла будет быстрее, чем запуск sed каждый раз и передача вывода в grep . Примечание: новый файл также будет иметь размер 244 МБ!

Следующим шагом является использование grep для поиска нового файла:

grep 'search term' json_file_with_breaks
1

sed - это почти то, что вам нужно, вот так:

sed 's/.*\(.\{100\} eubike.\{100\}\). */\1/'webshots-index-20121231-index.json

возвращает это на консоль:

20121017032138 "," warc ", 30012950425], [" eusbike "," 2012-11-11 09:41 "," 20121111040120/webshots.com-user-eusbike-20121111-094102.warc.gz ", 34212598," 20121111040120 "," warc ", 19238806437], [" EUSCALDUN "," 2012-11-17 13:

но и это большое НО: вы ограничены RE_DUP_MAX до 255 с обеих сторон. Даже для 100 показанных сторон на моем MacBook Pro потребовалось 16 минут. Всего 2 минуты по 10 символов с каждой стороны. У меня нет времени, чтобы проверить, сколько времени займет 255 с каждой стороны, вероятно, около 50 минут. Причины ограничения указаны в ftp://ftp.ics.uci.edu/pub/centos0/ics-custom-build/BUILD/nagios-plugins-1.4.13/gl/regex.h

Я думаю, что вам может не повезти, если вы хотите, чтобы вокруг вашего запроса было столько символов.

0

Это больше похоже на ваш оригинальный вопрос

Есть ли простая командная строка Unix, которую я могу ввести, которая позволяет мне выделять, скажем, 512 байт с обеих сторон поискового запроса?

Со страницы руководства grep :

-b, --byte-offset  
      Print the 0-based byte offset within the  input  file  before
      each  line  of output.  If -o (--only-matching) is specified,
      print the offset of the matching part itself.

Итак, вы можете искать свою строку следующим образом:

grep -o -b 'my search term' json_file

Выход:

1234567:my search term
9876543:my search term
...

Каждая строка содержит байтовое смещение от начала файла каждого вхождения «мой поисковый запрос».

Вы можете использовать cut -bN-M для выбора байтов от N-го до M-го в файле:

cut -b$((1234567 - 512))-$((1234567 + 512)) json_file
cut -b$((9876543 - 512))-$((9876543 + 512)) json_file

Вы можете автоматизировать вышеописанный процесс с помощью цикла в while

grep -o -b 'my search term' json_file | cut -d: -f1 | while read pos; do cut -b$((pos - 512))-$((pos + 512)); done

Это находит все вхождения «моего поискового термина» в файле, вырезает их позиции из вывода grep и для каждой позиции вырезает 512 байт по обе стороны от совпадения из файла json (в общей сложности 1024 байта вокруг матч).

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .