Сценарий загрузки файла Github с использованием curl, где имя файла И путь являются переменными

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 vs POSIX grep

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} .

2
14.04.2019, 16:22
2 ответа

Выполните 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-адрес загрузки.

1
27.01.2020, 22:17

Я разбил путь на (3 )части:

  1. Нет -Переменная база:Часть пути, которая является предсказуемой на 100% и не подлежит изменению в будущем

https://github.com/digitalocean/doctl/releases/download/

  1. Имя переменной DIRECTORY:Имя каталога — это номер версии. Так что, хотя это переменная, она все же предсказуема, потому что использует семантическое управление версиями (https://semver.org/):
  2. .

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 -, заполняющей

.
  1. Имя ФАЙЛА переменной:Операция следующего выражения извлекает только последнюю версию (" m 1 " части )имени файла:

$(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

Эта загрузка будет успешно выполняться без необходимости вручную редактировать сценарий, в котором имена файлов и каталогов изменятся в будущих выпусках.

Опять же, возможно, это не самое элегантное решение, но оно эффективно решает проблему. Если у вас есть лучший подход, пожалуйста, поделитесь! ХТХ-

0
27.01.2020, 22:17

Теги

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