Обратите внимание, что за исключением дополнительного кода в попытке 2, весь код фактически противоположен тому, что запрашивал OP. Как видно из попытки 2, команды легко адаптировать.
У меня был текстовый файл с 1.108.752 строками, размером около 83 МБ. Я хотел получить 46.744 строки от 15-й до 1.108.716-й строки, что в среднем примерно на каждую 24-ю строку.
ТЛ; др;
Вторая попытка быстрее, чем первая. Третий работает только для меньшего количества строк.
Первая попытка (плохо)
Для каждой строки, которую я хочу, sed
читает строки из начала текстового файла, но не печатает их (-n
). Когда он достигнет нужной мне строки, выведите его (p
), а затем закройте (q
) вместо чтения до конца файла. Затем сделайте это снова для следующего белья.
Очевидно, что это занимает немного больше времени для каждого запуска, потому что sed
должен проходить больше строк, чем раньше.
Если бы я рассчитал это право, в моем случае это заняло бы около 307332472188 проходов через текстовый файл в целом. Боже мой
Обратите внимание, что для этого подхода порядок строк не имеет значения в файле белья.
while read line; do
sed -n "${line}{p;q}" "${INFILE}"
done
Результаты синхронизации: 2568.80s user 256.10s system 92% cpu 51:00.37 total
. Не хорошо.
Вторая попытка (лучше)
Это читает номера белья из файла и добавляет p
(опять же, для печати этой строки). Эта строка передается следующему sed
, который читает из файла (-f
), который здесь представляет собой STDIN
записываемый как -
, который каждый раз является выводом первого sed
, который фактически является номером белья, который будет напечатан:
sed 's/$/p/' "${LINENUMS}" | sed -n -f - "${INFILE}"
Результаты синхронизации: 146.54s user 0.18s system 100% cpu 2:26.70 total
. Довольно хорошо!
Если вы хотите , чтобы не печатать строки из linefile (как OP хотел сделать), немного изменить команду так , что номера строк в настоящее время d eleted вместо р rinted и печатать все остальные строки вместо их удаления (-n):
sed 's/$/d/' "${LINENUMS}" | sed -f - "${INFILE}"
Третья попытка (баддер)
Это не сработало для меня, потому что у меня было слишком много строк, которые я хотел извлечь. Это должно работать для (намного) меньшего количества строк, хотя, но я не знаю предел этому.
Я попытался создать длинную строку для sed, что, как я ожидал, приведет к тому, что sed
будет проходить через файл только один раз (!), Не печатая ничего, кроме номеров белья из строки:
sed -n "12p;15p;24p;345p;...;12345;" ${INFILE}"
но это привело бы к строке длиной около 420076
символов, которая при загрузке в sed
просто приводила к sed: Argument list is too long
. Что понятно.