Печать строк вокруг позиции в файле - PullRequest
0 голосов
/ 17 апреля 2020

Я импортирую большой файл CSV (5 ГБ) в BiqQuery, и у меня была информация об ошибке в файле и его позиции, указанной в байтовом смещении от начала файла (например, 134683757). Я хотел бы взглянуть на строки вокруг этой позиции ошибки.

Некоторые примеры строк файла:

field1, field2, field3
abc, bcd, efg
...
dge, hfr, kdf,
dgj, "a""a", fbd # in this line is an invalid csv element and I get error, let's say on the position 134683757 
skd, frd, lqw
...
asd, fij, fle

Мне нужна команда для отображения строк вокруг ошибки, например

dge, hfr, kdf,
dgj, "a""a", fbd 
skd, frd, lqw

Я пробовал sed и awk, но не нашел простого решения.

1 Ответ

1 голос
/ 18 апреля 2020

Из первоначальной версии вопроса было определенно не ясно, что вы получили только байтовое смещение от начала файла.

Вам нужно получить лучшую позицию от программного обеспечения, генерирующего ошибку; разработчик был ленив в сообщении непригодного числа. Разумно запросить номер строки (и предпочтительно смещение внутри строки), а не (или также) смещение байта от начала.

Предполагая, что число является позицией байта в файле, это становится сложно. Большинство Unix утилит работают со строками (переменной длины). Я бы соблазнился написать какой-нибудь код C, чтобы выполнить эту работу, но это может быть за вас (и вам не стыдно).

Если это не удастся, ваша лучшая команда, скорее всего, dd. Если сообщаемое число равно 134683757, то я предполагаю, что ваши строки, вероятно, не превышают 1 КиБ каждая (скорректируйте числа, если они больше или меньше), а затем используйте:

 dd if=big.csv of=extract.csv bs=1 skip=$((134683757 - 3 * 1024)) count=6144
 echo >> extract.csv

Вы бы тогда посмотрели на extract.csv. Необработанный вывод dd, вероятно, не будет иметь новой строки в конце последней строки (echo >>extract.csv исправляет это). Вывод, вероятно, начнется частично через запись и закончится частично через другую запись. Тем не менее, вы, скорее всего, будете иметь соответствующую информацию, а также некоторую несущественную информацию Как я уже сказал, скорректируйте числа в соответствии с конкретной ситуацией.

Самая хитрая часть - это точное определение смещения байта в файле, который вы получаете. С пользовательским кодом C, который может быть предоставлен легко (более легко). С выводом из dd вы должны выполнить вычисления самостоятельно.

awk -v offset=$((134683757 - 3 * 1024)) '
    { printf "%9d: %s\n", offset, $0; offset += length($0) + 1 }
    ' extract.cvs

Это берет начальное смещение из команды dd и ставит префикс (остатки) первой строки с этим числом и данные; затем он добавляет длину к смещению плюс единицу для новой строки, которая не была учтена, и продолжается до конца файла. Это дает вам начальное смещение для каждой строки в извлеченных данных. Вы можете увидеть, где был ваш фактический старт, посмотрев на смещения - вы должны быть в состоянии определить, какая это была запись.

Вы можете использовать вариант этого скрипта Awk, который построчно читает весь файл, и отслеживает смещение (а также номера строк) и печатает данные, когда они добираются до места, где у вас возникла проблема.

В давние времена мне приходилось иметь дело с данными от 1/2 дюйма магнитные ленты (те большие круглые ленты, которые вы видите в старых фильмах), где файлы, сгенерированные на мейнфрейме, казались разумно отформатированными для первых нескольких десятков мегабайт, но затем формат изменился на какой-то альтернативный формат для нескольких мегабайт, а затем вернулся к Оригинальный формат еще раз. Я так и не узнал почему; Я только что научился с этим бороться. Метод проб и ошибок!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...