GNU grep может захватывать контекст по строкам ( -A LINES
для контекста после , -B LINES
для контекста до и -C LINES
для контекста как до, так и после) но у него нет флажка для горизонтального контекста. Вы можете сделать это с помощью регулярного выражения:
grep -Eo '.{0,10}media.{0,10}'
( -E
использует Расширенные регулярные выражения (ERE), что позволяет использовать синтаксис типа . {0,10}
] (соответствует любому символу 0–10 раз). GNU grep -o
отображает только совпадающий контент, по одному совпадению в строке.)
Обратите внимание, это победило Это не полный список, так как некоторые копии слова «медиа» могут быть слишком близки к тому, что уже записано. Например:
$ echo 123 media 12345 media 123456789 media 12 |grep -Eo '.{0,10}media.{0,10}'
123 media 12345 med
234567890 media 123
Вы получаете части всех трех экземпляров «media», но поскольку один из них частично находится в пределах десяти символов от другого, была представлена только его часть.
Если GNU grep скомпилирован с libpcre , вы можете указать этим подстановочным знакам ленивыми, а не жадными :
$ echo 123 media 12345 media 123456789 media 12 |grep -Po '.{0,10}?media.{0,10}?'
123 media
12345 media
234567890 media
Флаг -P
включает Оценка Perl-совместимого регулярного выражения (PCRE).
Ленивая оценка (также называемая «нежадной оценкой») направлена на то, чтобы одно совпадение не мешало другому, а не потребляло как можно больше из десяти символов, что ограничивает дальнейшие совпадения.
Если ваша версия grep
не поддерживает -P
или -o
, вы можете использовать perl
:
$ echo 123 media 123 media 123456789 media 12 |perl -ne \
'while (/(.{0,10}?media.{0,10}?)/g) { print "$1\n"; }'
123 media
12345 media
234567890 media
Это немного изменяет регулярное выражение, чтобы включить соответствующую группу, чтобы мы могли ссылаться на согласованный текст позже. В противном случае это просто цикл для каждого совпадения ( g
соответствует глобально, а не только в первый раз), который затем печатает совпадение с новой строкой.
GNU grep добавляет множество функций поверх стандартного grep POSIX . Конкретно для этого ответа: -A LINES
(строки контекста a fter), -B LINES
(строки контекста b efore) , -C LINES
(строки c в тексте до и после), -o
(показать o только совпадение) и -P
(используйте P CRE) все доступны в GNU grep, но не могут использоваться для других реализаций grep. BSD grep поддерживает все из них, кроме -P
, но GNU grep часто предпочитается пользователями BSD из-за оптимизации производительности GNU .
Команды GNU и BSD grep
также поддерживают - color
, который можно использовать как альтернативу -o
. Это приведет к отображению целых строк с соответствующим цветом текста («медиа» плюс его 0–10 символов контекста).
Последнее замечание: в комментарии к вопросу использовался синтаксис . {, 5}
, который работает в grep -E
, но почти нигде больше (конечно, ни grep -P
или perl
). Плохая привычка использовать этот формат вместо того, чтобы явно указывать ноль в . {0,5}
.
Выполните curl -sL
(, чтобы сбросить индикатор выполнения и следовать перенаправлениям ), как и вы, но укажите URL-адрес последней версии Linux -amd64:
curl -sL "$(curl -L -s https://api.github.com/repos/digitalocean/doctl/releases/latest |
jq -r '.assets[] | select(.name | contains("-linux-amd64.tar.gz")).browser_download_url')" |
tar -xzv
Подстановка внутренней команды запрашивает у github API последнюю версию этого репозитория; затем он передает его через jq
, чтобы выбрать элемент, имя которого содержит строку -linux-amd64.tar.gz
, и вернуть URL-адрес загрузки.
Я разбил путь на (3 )части:
https://github.com/digitalocean/doctl/releases/download/
v$(curl -s https://github.com/digitalocean/doctl/releases/ | grep -om 1 'doctl-.*-linux-amd64.tar.gz'|grep -Eo '[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}')/
Операция заключается в поиске самого последнего файла и извлечении из него номера версии. Поскольку «v » в имени каталога не является частью имени файла, его нельзя захватить с помощьюgrep.Итак, я просто жестко закодировал -перед переменной self -, заполняющей
.$(curl -s https://github.com/digitalocean/doctl/releases/ | grep -om 1 'doctl-.*-linux-amd64.tar.gz')
Вся эта уродливая штука выглядит следующим образом (с " | tar -xzv " на конце):
curl -sL https://github.com/digitalocean/doctl/releases/download/v$(curl -s https://github.com/digitalocean/doctl/releases/ | grep -om 1 'doctl-.*-linux-amd64.tar.gz'|grep -Eo '[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}')/$(curl -s https://github.com/digitalocean/doctl/releases/ | grep -om 1 'doctl-.*-linux-amd64.tar.gz') | tar -xzv
Эта загрузка будет успешно выполняться без необходимости вручную редактировать сценарий, в котором имена файлов и каталогов изменятся в будущих выпусках.
Опять же, возможно, это не самое элегантное решение, но оно эффективно решает проблему. Если у вас есть лучший подход, пожалуйста, поделитесь! ХТХ-