Извлеките данные между двумя шаблонами из огромного (принудительного) текстового файла

wget (по крайней мере, 1.16.3) не позволяет пользователю указывать настраиваемые атрибуты. Было предложено расширить параметр - follow-tags синтаксисом вроде - follow-tags = a / href , но никто не последовал на этом.

Если вы не против применить быстрый взлом wget для поддержки вашего сценария, см. этот коммит , чтобы узнать о работе, необходимой для добавления пользовательских тегов или атрибутов.

Как вариант, вы можете написать постпроцессор самостоятельно.

-3
26.11.2018, 01:21
1 ответ

TL;DR

В кш, баш, зш:

sed -e $'s,"title":,\1,g' -e $'s,"url":,\2,g' -e $'s,^[^\1]*,,' -e $'
         s,\1\\([^\2]*\\)\2[^\1]*,\\1\\\n,g' infile

сед

Односимвольные разделители.

Каноническое решение для односимвольных разделителей давайте предположим, что @и #в качестве примера, это:

sed 's,^[^@]*,,;s,@\([^#]*\)#[^@]*,\1,g' infile

Это будет -удалить с начала все символы, которые не являются @-извлечь символы, находящиеся между первыми@к следующему первому#следующему.

Для каждой строки входного файла infile.

Общие разделители.

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

sed -e 's,"title":,@,g' -e 's,"url":,#,g' -e 's/^[^@]*//;s/@\([^#]*\)#[^@]*/\1 /g' infile

Вместо пробела(\1)в вашем случае можно использовать символы новой строки,которые написаны для GNU sed, просто(\1\n):

sed -e 's,"title":,@,g' -e 's,"url":,#,g' -e 's/^[^@]*//;s/@\([^#]*\)#[^@]*/\1\n/g' infile

Для других (более старых )seds Добавить явный перевод строки:

sed -e 's,"title":,@,g' -e 's,"url":,#,g' -e 's/^[^@]*//;s/@\([^#]*\)#[^@]*/\1\
/g' infile

Если существует риск того, что использованные выше разделители могут находиться внутри файла, выберите другие разделители, которые не должны существовать внутри файла. Если это кажется проблемой, начальный и конечный разделители могут быть управляющими символами. например Ctrl-A(или закодировано :^A, как шестнадцатеричное:Ox01или как восьмеричное\001). Вы можете ввести это в консоли оболочки, набрав Ctrl-VCtrl-A . Вы увидите ^A в командной строке:

sed -e 's,"title":,^A,g' -e 's,"url":,^B,g' -e 's,^[^^A]*,,;s,^A\([^^B]*\)^B[^^A]*,\1\n,g' infile

Или, если это слишком громоздко печатать, используйте (ksh,bash,zsh):

sed -e $'s,"title":,\1,g' -e $'s,"url":,\2,g' -e $'s,^[^\1]*,,' -e $'s,\1\\([^\2]*\\)\2[^\1]*,\\1\\\n,g' infile

Или, если ваш sed поддерживает это:

sed -e 's,"title":,\o001,g' -e 's,"url":,\o002,g' -e 's,^[^\o001]*,,' -e 's,\o001\([^\o002]*\)\o002[^\o001]*,\1\o012,g' infile

если разделителем является "описание":

Если начальный тег на самом деле"description":(из вашего примера вывода ), просто используйте его вместо"title":

Вывод выше (из файла, на который вы ссылались ранее в своем вопросе):

"Black Friday deal: Palm companion phone is $150 off at Verizon, but there's a catch","description":"",
"LG trademarks potential names for its foldable phone, one fits a crazy concept found in patents","description":"",
"Blackview's Black Friday promo discounts the BV9500 Pro and other rugged phones on Amazon","description":"Advertorial by Blackview: the opinions expressed in this story may not reflect the positions of PhoneArena! disclaimer   amzn_assoc_tracking_id = 'phone0e0d-20';amzn_assoc_ad_mode = 'manual';amzn_assoc_ad_type...",

Если вам нужно пронумеровать строки, повторите это с помощьюsed -n '=;p;g;p':

| sed -n '=;p;g;p'
1
"Black Friday deal: Palm companion phone is $150 off at Verizon, but there's a catch","description":"",

2
"LG trademarks potential names for its foldable phone, one fits a crazy concept found in patents","description":"",

3
"Blackview's Black Friday promo discounts the BV9500 Pro and other rugged phones on Amazon","description":"Advertorial by Blackview: the opinions expressed in this story may not reflect the positions of PhoneArena! disclaimer   amzn_assoc_tracking_id = 'phone0e0d-20';amzn_assoc_ad_mode = 'manual';amzn_assoc_ad_type...",

АВК

Аналогичная логика реализована в awk:

awk -vone=$'\1' -vtwo=$'\2' '{
            gsub(/"title":/,one);
            gsub(/"url":/,two);
            sub("^[^"one"]*"one,"")
            gsub(two"[^"one"]*"one,ORS)
            sub(two"[^"two"]*$","")
           } 1' infile
1
28.01.2020, 05:19

Теги

Похожие вопросы