фильтрация данных на основе разделителя в оболочке

Мне понравилась идея Stéphane Chazelas использовать Lynx и LYNX_PRINT_TITLE, но этот скрипт не работал у меня в Ubuntu 14.04.5.

Я сделал упрощенную версию, запустив Lynx и предварительно сконфигурировав файлы.

Добавьте следующую строку в файл /etc/lynx-cur/lynx.cfg (или туда, где находится ваш lynx.cfg):

PRINTER:P:printenv LYNX_PRINT_TITLE>/home/account/title.txt:TRUE:1000

Эта строка предписывает сохранять заголовок при печати в «/home/account/title. txt" - вы можете выбрать любое имя файла. Вы запрашиваете ОЧЕНЬ большие страницы, увеличьте указанное выше значение с «1000» до любого количества строк на странице, которое вы хотите, иначе Lynx выдаст дополнительный запрос «при печати документа, содержащего очень большое количество страниц».

Затем создайте файл /home/account/lynx-script.txt со следующим содержимым:

key p
key Select key
key ^J
exit

Затем запустите Lynx, используя следующие параметры командной строки:

lynx -term=vt100 -display_charset=utf-8 -nopause -noprint -accept_all_cookies -cmd_script=/home/account/lynx-script.txt "http://www.youtube.com/watch?v=Dd7dQh8u4Hc" >/dev/nul

После выполнения этой команды файл /home/ account/title.txt будет создан с заголовком вашей страницы.

Короче говоря, вот функция PHP, которая возвращает заголовок страницы на основе заданного URL-адреса или false в случае ошибки.

function GetUrlTitle($url)
{
  $title_file_name = "/home/account/title.txt";
  if (file_exists($title_file_name)) unlink($title_file_name); // delete the file if exists
  $cmd = '/usr/bin/lynx -cfg=/etc/lynx-cur/lynx.cfg -term=vt100 -display_charset=utf-8 -nopause -noprint -accept_all_cookies -cmd_script=/home/account/lynx-script.txt "'.$url.'"';
  exec($cmd, $output, $retval);
  if (file_exists($title_file_name))
  {
    $title = file_get_contents($title_file_name);
    unlink($title_file_name); // delete the file after reading
    return $title;
  } else
  {
    return false;
  }
}

print GetUrlTitle("http://www.youtube.com/watch?v=Dd7dQh8u4Hc");
0
13.10.2016, 14:46
4 ответа

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

$ perl -lne '$h{$_}++ for /(?<=\|).*?(?=\|)/g; END{print for keys %h}' file
short
b4-124
lol
yes
bad-girl
lab
yoo
good-guy
hub
dummy
hello
a4-123
wow

Смотрите создание хэша с помощью regex в perl

2
28.01.2020, 02:15

Ваш вывод имеет "фиктивное" повторение. Вот что я получаю со сценарием ниже -

   awk -f f1.awk /tmp/f1
    short
    hub
    wow
    hello
    a4-123
    b4-124
    yes
    yoo
    lol
    bad-girl
    good-guy
    lab
    dummy

    cat f1.awk 
    {
      n=split($1,a,"|")

      for(i=2; i<n; i++) {
        arr[a[i]] = a[i] 
      } 
    }   
    END{
      for (var in arr) 
        print(var)  
    }
0
28.01.2020, 02:15

как насчет следующего?

cut file -d'|' -f2,3,4 | tr '|' '\n'

Приведенная выше команда напечатает фиксированное количество столбцов (3). Если вы хотите напечатать переменное количество столбцов до первого появления / , вы можете использовать что-то вроде:

cut -d'/' -f1 file | cut  -d'|' -f2- | tr '|' '\n'
2
28.01.2020, 02:15

Если у вас есть grep с опцией pcre :

$ grep -oP '\|\K[^|]+(?=\|)' ip.txt | sort -u
a4-123
b4-124
bad-girl
dummy
good-guy
hello
hub
lab
lol
short
wow
yes
yoo
  • -o печатать только соответствующий шаблон
  • -P используйте pcre regex
  • \ | \ K положительный просмотр назад, чтобы увидеть, есть ли | до того, как наша строка будет извлечена {{1} }
    • аналогично, (? = \ |) положительный просмотр вперед, чтобы увидеть, есть ли | после извлекаемой строки
  • [^ |] + строка для извлечения - просто инвертируйте | и получите один или несколько таких символов
  • sort -u , чтобы получить уникальное значение

Если вы хотите сохранить порядок, в котором находятся эти строки:

$ grep -oP '\|\K[^|]+(?=\|)' ip.txt | awk '!seen[$0]++'
yoo
dummy
yes
wow
hub
lab
short
hello
good-guy
bad-girl
lol
a4-123
b4-124
3
28.01.2020, 02:15

Теги

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