Объедините URL в bash с xargs
Я пытаюсь построить URL-адреса из вывода с одной записи в строке. Я попробовал это:
<stuff> | xargs -L1 -I {} echo "${url}&page=queryresults&j="{}
Однако для некоторых длинных строк (у них нет пробела, но могут быть тире и подчеркивания), я получаю '{}', где я ожидаю строку, сгенерированную <stuff>
, Если я добавлю пробел между последней двойной кавычкой и {}, это сработает, но у меня есть лишний пробел, который мне не нужен:
<stuff> | xargs -L1 -I {} echo "${url}&page=queryresults&j=" {}
Точно так же, если я удаляю &page=queryresults
немного, это работает. Понятия не имею почему.
Что мне здесь не хватает?
Это работает для этого:
blajob_123abcd_1234567890x
Но не это: SomeTask_some_long_project_name_with_cumulative_metrics_YYYYMMDD_2018_08_15T00_12345a67b8-scheduled-run-bla-bla-bla-yadda
1 ответ
Там нет необходимости для xargs
здесь вообще, и тебе лучше без этого. Следующее гарантированно будет работать корректно на всех POSIX-совместимых оболочках:
while IFS= read -r line; do
printf '%s&page=queryresults&j=%s\n' "$url" "$line"
done
Почему бы не придерживаться xargs -I {} echo "$url&...&j={}"
?
xargs -I
Спецификация включает в себя следующий текст: Сформированные аргументы не могут быть больше 255 байт. Если ваш URL длинный, это может привести к усечению, которое, по-видимому, соответствует описанным деталям.xargs -I
включено только в расширения XSI для POSIX; платформы, которые не претендуют на реализацию этих расширений, не обязаны предоставлять его или, если они это делают, вести себя как-то определенным образом.- Если вы использовали
xargs printf "$url..."
(подставляя URL в форматную строку, а не через заполнитель), у вас будут ошибки, если ваш URL содержит%
приметы. - Если вы использовали
echo
, вы бы имели неопределенное поведение, если бы ваш URL содержал буквальную обратную косую черту (см. раздел ИСПОЛЬЗОВАНИЕ ПРИЛОЖЕНИЯ спецификации POSIX дляecho
).
Тем не менее, если вы действительно хотите использовать xargs
рассмотрим (в системах GNU):
xargs -d $'\n' printf "${url//%/%%}"'&page=queryresults&j=%s\n'
... или на платформе с инструментами BSD:
tr '\n' '\0' | xargs -0 printf "${url//%/%%}"'&page=queryresults&j=%s\n'
Замечания:
- Потому что мы не используем
-I
ограничение в 255 символов не применяется вообще. (Так же,xargs
способен передать столько аргументов каждому экземпляру/usr/bin/printf
as будет соответствовать его командной строке, а не ограничиваться одним аргументом на вызов). - В URL мы заменяем любые
%
литералы с%%
, Если URL-адрес уже правильно закодирован, он не должен содержать обратной косой черты (их уже следовало заменить на%5C
). - Расширение GNU
-d
используется для указания того, что только новые строки должны рассматриваться как разделители между словами, которые должны рассматриваться как аргументы; это также предотвращает синтаксический анализ и использование буквальных кавычекxargs
сам. На платформах BSD, преобразование новых строк в NUL и использование-0
служит заменой.