如何将逗号分隔的列表作为参数提供给下一个命令

yuk*_*say 9 pipe xargs arguments

我有一个脚本s1,它输出一个用 ',' 分隔的数字列表,例如1,2,3,4. 现在我想将这些数字s2作为参数提供给脚本,以便 s2 将在每个数字上运行并在单独的行中输出其结果。例如,如果 s2 将数字乘以 2,这将是我正在寻找的结果:

2
4
6
8
Run Code Online (Sandbox Code Playgroud)

我现在正在做的是:

s1 | xargs -d "," | xargs -n1 s2
Run Code Online (Sandbox Code Playgroud)

但是我觉得我这样做很愚蠢!所以我的问题是:

正确的做法是什么?

我的解决方案的问题是它两次调用 xargs 并迭代输入两次,这在我看来当然是不合理的!答案xargs -d "," -n1似乎不错,但我不确定它是否只迭代一次。如果是这样,请在您的回答中验证这一点,我会接受。顺便说一句,我宁愿不使用 Perl,因为它仍在迭代两次,而且 Perl 在许多系统上可能不存在。

Geo*_*sen 19

这也应该同样有效:

s1 | xargs -d "," -n1 s2
Run Code Online (Sandbox Code Playgroud)

测试用例:

printf 1,2,3,4 | xargs -d ',' -n1 echo
Run Code Online (Sandbox Code Playgroud)

结果:

1
2
3
4
Run Code Online (Sandbox Code Playgroud)

如果s1输出该列表后跟一个换行符,则您希望将其删除,否则最后一次调用将使用4\n而不是4

s1 | tr -d '\n' | xargs -d , -n1 s2
Run Code Online (Sandbox Code Playgroud)


Jef*_*ler 7

如果s2可以接受多个参数,你可以这样做:

(IFS=,; ./s2 $(./s1))
Run Code Online (Sandbox Code Playgroud)

它暂时将 IFS 覆盖为逗号,全部位于子外壳中,以便s2看到s1由逗号分隔的输出。subshel​​l 是一种无需保存或重置前一个值即可更改 IFS 的快捷方式。

此答案的先前版本不正确,可能是由于剩余的 IFS 设置破坏了结果。由于ilkkachu指出我的错误

要手动循环输出并将它们单独提供给s2,这里演示了 IFS 的保存和重置:

oIFS="$IFS"
IFS=,
for output in $(./s1); do ./s2 "$output"; done
IFS="$oIFS"
Run Code Online (Sandbox Code Playgroud)

或者像以前一样在子 shell 中运行 IFS 位:

(
IFS=,
for output in $(./s1); do ./s2 "$output"; done
)
Run Code Online (Sandbox Code Playgroud)