用 xargs 连接 bash 中的 URL
Concatenate URL in bash with xargs
我正在尝试从每行一个条目的输出构建 URL。我试过这个:
<stuff> | xargs -L1 -I {} echo "${url}&page=queryresults&j="{}
但是,对于一些长行(它们没有 space 但可以有破折号和下划线),我得到 '{}' 我希望 <stuff>
生成的字符串.如果我在最后的双引号和 {} 之间添加一个 space 它可以工作,但我有一个额外的 space 我不想要:
<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
这里根本不需要 xargs
,没有它你会过得更好。以下保证在所有符合 POSIX 的 shell 上正常工作:
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
仅包含在 POSIX 的 XSI 扩展中;不声称实现这些扩展的平台不需要提供它,或者如果它们提供,也不需要以任何特定方式运行。
- 如果您使用
xargs printf "$url..."
(将 URL 替换为格式字符串而不是通过占位符),如果您的 URL 包含 %
符号,您将遇到错误.
- 如果您使用
echo
,如果您的 URL 包含文字反斜杠(请参阅 the POSIX specification for echo
的应用程序使用部分),您将有未指定的行为。
也就是说,如果您真的想要使用xargs
,请考虑(在 GNU 系统上):
xargs -d $'\n' printf "${url//%/%%}"'&page=queryresults&j=%s\n'
...或者,在带有 BSD 工具的平台上:
tr '\n' '[=12=]' | xargs -0 printf "${url//%/%%}"'&page=queryresults&j=%s\n'
注:
- 因为我们没有使用
-I
,所以 255 个字符的限制根本不适用。 (类似地,xargs
能够将尽可能多的参数传递给 /usr/bin/printf
的每个实例,以适应其命令行,而不是每次调用仅限于一个参数)。
- 在 URL 中,我们将任何
%
文字替换为 %%
。如果 URL 已经正确编码,它不应包含任何反斜杠(它们应该已经被 %5C
替换)。
- GNU 扩展
-d
用于指定只有换行符应被视为要作为参数的单词之间的分隔符;这也可以防止 xargs
本身解析和使用文字引号。在 BSD 平台上,将换行符转换为 NUL 并使用 -0
作为替代。
我正在尝试从每行一个条目的输出构建 URL。我试过这个:
<stuff> | xargs -L1 -I {} echo "${url}&page=queryresults&j="{}
但是,对于一些长行(它们没有 space 但可以有破折号和下划线),我得到 '{}' 我希望 <stuff>
生成的字符串.如果我在最后的双引号和 {} 之间添加一个 space 它可以工作,但我有一个额外的 space 我不想要:
<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
这里根本不需要 xargs
,没有它你会过得更好。以下保证在所有符合 POSIX 的 shell 上正常工作:
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
仅包含在 POSIX 的 XSI 扩展中;不声称实现这些扩展的平台不需要提供它,或者如果它们提供,也不需要以任何特定方式运行。- 如果您使用
xargs printf "$url..."
(将 URL 替换为格式字符串而不是通过占位符),如果您的 URL 包含%
符号,您将遇到错误. - 如果您使用
echo
,如果您的 URL 包含文字反斜杠(请参阅 the POSIX specification forecho
的应用程序使用部分),您将有未指定的行为。
也就是说,如果您真的想要使用xargs
,请考虑(在 GNU 系统上):
xargs -d $'\n' printf "${url//%/%%}"'&page=queryresults&j=%s\n'
...或者,在带有 BSD 工具的平台上:
tr '\n' '[=12=]' | xargs -0 printf "${url//%/%%}"'&page=queryresults&j=%s\n'
注:
- 因为我们没有使用
-I
,所以 255 个字符的限制根本不适用。 (类似地,xargs
能够将尽可能多的参数传递给/usr/bin/printf
的每个实例,以适应其命令行,而不是每次调用仅限于一个参数)。 - 在 URL 中,我们将任何
%
文字替换为%%
。如果 URL 已经正确编码,它不应包含任何反斜杠(它们应该已经被%5C
替换)。 - GNU 扩展
-d
用于指定只有换行符应被视为要作为参数的单词之间的分隔符;这也可以防止xargs
本身解析和使用文字引号。在 BSD 平台上,将换行符转换为 NUL 并使用-0
作为替代。