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

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

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

2
4
6
8

我现在正在做的是:

s1 | xargs -d "," | xargs -n1 s2

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

正确的做法是什么?

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

答案1

这也应该同样有效:

s1 | xargs -d "," -n1 s2

测试用例:

printf 1,2,3,4 | xargs -d ',' -n1 echo

结果:

1
2
3
4

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

s1 | tr -d '\n' | xargs -d , -n1 s2

答案2

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

(IFS=,; ./s2 $(./s1))

它暂时将 IFS 覆盖为逗号,全部在子 shell 中,以便看到由逗号分隔s2的输出。s1子 shell 是一种更改 IFS 的快捷方法,无需保存先前的值或重置它。

此答案的先前版本不正确,可能是由于剩余的 IFS 设置导致结果损坏。谢谢伊尔卡丘为了指出我的错误

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

oIFS="$IFS"
IFS=,
for output in $(./s1); do ./s2 "$output"; done
IFS="$oIFS"

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

(
IFS=,
for output in $(./s1); do ./s2 "$output"; done
)

答案3

尝试这个:

s1 | perl -pe 's/,/\n/g' | xargs -n1 s2

相关内容