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)
如果s2
可以接受多个参数,你可以这样做:
(IFS=,; ./s2 $(./s1))
Run Code Online (Sandbox Code Playgroud)
它暂时将 IFS 覆盖为逗号,全部位于子外壳中,以便s2
看到s1
由逗号分隔的输出。subshell 是一种无需保存或重置前一个值即可更改 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)