使用 xargs 和管道将标准输出转换为不接受多个单词的原始数据

使用 xargs 和管道将标准输出转换为不接受多个单词的原始数据

我当前正在运行命令:echo "hello world" | xargs curl http://localhost:8080/function/func_wordcount -d"它获取标准输出echo "hello world",然后通过管道将其传递给func_wordcount使用-d选项。该-d选项用于发送原始数据,myfunc_wordcount接受原始数据输入并打印单词数和字母数。

例如,当我写入时,echo "hello" | xargs curl http://localhost:8080/function/func_wordcount -d"输出为: 1, 5 表示有一个单词包含 5 个字母。

但是,当我尝试包含许多单词时,我收到错误。当我写入时,echo "hello world" | xargs curl http://localhost:8080/function/func_wordcount -d"我得到输出 1, 5,然后是一个带有错误的换行符:curl: (6) could not resolve host: world。所以我很确定当我使用该选项将标准输出转换为原始数据时,它会将 hello world 分成两个单词-d

另外,只是为了表明该函数无需管道和转换即可工作,当我运行函数时,curl http://localhost:8080/function/func_wordcount -d "hello world"我得到 2, 11 显示有两个单词和 11 个字符。

我的问题是如何解决这个分裂问题。我觉得令人困惑的部分是为什么它只解析输入的前半部分并完成它,然后在第二部分抛出错误而不是只发送一块数据。我只能发送根本不由空格分隔的输入,因此功能的使用变得非常有限。

答案1

就是这样xargs。它在其标准输入上接受一个单词列表(空白或换行符分隔,也理解某种形式的引用)并传递他们作为它运行的命令的参数。

在这里,如果您想hello word作为一个参数传递给curl,您需要:

echo '"hello world"' | xargs curl...

其中xargs将它们理解为一种引用机制,以防止和"..."之间的空格被视为参数分隔符。也理解and (与 POSIX shell 的方式不同)。helloworldxargs\'...'

使用 GNU xargs,您还可以指定分隔符。例如:

echo hello world | xargs -d '\n' curl...

只有换行符才会被理解为分隔符(而不是空格),并且引用机制被禁用。

这使您可以将每一行(而不是每个单词)的内容作为参数传递给命令。

虽然-d在 GNU 之外很少受支持xargs-0但它的另一个扩展(用于对 NUL 进行定界并禁用引号处理)得到了更广泛的支持。所以你也可以这样做:

echo hello world | tr '\n' '\0' | xargs -0 curl...

如果有多行输入,xargs会将所有行作为单独的参数传递给curl.如果您想curl为每一行调用一个,您可以添加一个-n 1选项。

您还可以使用:

echo hello world | xargs -I@@ curl... @@

curl对每一行调用一个,但请注意,前导空白被删除,并且xargs仍然进行一些引号处理,因此应该避免任意数据。

答案2

来自GNU xargs 手册页:

xargs从标准输入读取项目,分隔符空白(可以用双引号、单引号或反斜杠进行保护)或者 换行符,并使用任何初始参数执行该命令一次或多次,后跟从标准输入读取的项目。

即默认行为是输入中的任何空格都充当分隔符,因此hello world确实会产生两个参数。

如果你希望 xargs 保持整行完整,请使用 `xargs -d '\n' (在 GNU xargs 中,我不记得其他的了)。

但是,这仍然会导致多行输入给出curl多个参数。如果您想避免这种情况,并curl为每个输入行运行一次命令,请使用xargs -d '\n' -n 1.

如果您的输入仅包含一行,您不妨使用命令替换而不是管道:

curl http://... -d "$(echo "hello world")"

相关内容