
У меня есть очень длинная серия URL-адресов без разделительных символов, в том же формате, что и ниже:
http://example.comhttp://example.nethttp://example.orghttp://etc...
Я хочу, чтобы каждый URL был на новой строке. Я пытался сделать это, заменив все вхождения "http://" на "\nhttp://" с помощью sed
sed 's_http://_\nhttp://_g' urls.txt
но происходит ошибка сегментации (нарушение памяти). Я могу только предположить, что сам размер файла (более 100 ГБ) заставляет sed превышать некий предел.
Я мог бы разделить файл на несколько файлов меньшего размера для обработки, но все вхождения «http://» должны были бы остаться нетронутыми.
Есть лучший способ сделать это?
решение1
С помощью этого awk
вы сможете избежать чтения большого объема текста за один раз:
awk -vRS='http://' -vORS='\nhttp://' 1 urls.txt > urlsperline.txt
Успех может зависеть от используемой awk
реализации. Например, gawk
работает нормально, но mawk
вылетает.
решение2
Это сделает работу:
perl -pe 'BEGIN { $/ = "//" } s!(?=http://\z)!\n!' urls.txt
Установив$/, я изменил определение строки, так что она заканчивается на //
вместо новой строки. Это заставляет Perl читать по одному URL за раз. Маловероятно, что URL содержит //
except после схемы, но это нормально, если это так, регулярное выражение не даст ему добавлять ложные новые строки.
Если вы хотите избежать добавления пустой строки перед первым URL:
perl -pe 'BEGIN { $/ = "//"; print scalar <> } s!(?=http://\z)!\n!' urls.txt
Вы можете попробовать провести бенчмаркинг, чтобы увидеть, что s!http://\z!\nhttp://!
быстрее. Они эквивалентны. Обратите внимание, что /g
флаг не нужен при замене, потому что может быть только одно совпадение на «строку».
решение3
- Замените все вхождения a
:
на новую строку, чтобы разбить файл. - Заменять
http
в конце строки с- новая строка, за которой следует
http:
и добавление к ней следующей строки
- Повторите один раз, чтобы обновить четные и нечетные строки.
Эти шаги выглядят так:
tr ':' '\n' | sed -e '/http$/{N;s/http\n/\nhttp:/}' | sed -e '/http$/{N;s/http\n/\nhttp:/}'
Проверьте, есть ли строки, которые не начинаются с
http://
, выведите номера строк. Это произойдет только в том случае, если : находится где-то в URL, кроме как послеhttp
.grep -nv '^http://'